Navigate黑客松物联网行为分析分析和逻辑
给定一些json数据,是电动车的行为数据。主要是GPS相关的数据。
例如:
1 {"devId":"87AECCA3","timestamp":1539075913,"latitude":30.18781,"longitude":120.19133333333333,"satellite":8,"hdop":0.97,"altitude":11.2,"speed":0.0,"direction":137.35} 2 {"devId":"CD7FDC41","timestamp":1539076207,"latitude":30.1904,"longitude":120.19162833333333,"satellite":13,"hdop":0.82,"altitude":10.1,"speed":0.0,"direction":192.58}
给定一个红绿灯,让判断这个数据中包含的小车对象在路口的行为是等待还是行动,行动的话第一是不是闯红灯,第二闯红灯是左拐还是右拐还是直行。
另外两个问题是上高架和画轨迹的问题,在高架上和下目前主要是通过精确的高度过滤得到。画图主要是上传到百度的鹰视里面去看一下基本的轨迹。略微实现了一点点的绑路的拟合。
但是重点是路口行为的判断。拿到数据之后首先过滤一下重复的数据,然后找到同一个对象的数据,然后按照时间序列拍一下队。
其次根据路口坐标就可以用三角函数判断旋转的角度和方向。辅助的话还设定四个线段。以路口为中心,左右方向,上下方向和斜着的两个方向。
如果移动轨迹和这四条有限长度的线段有相交的话也是可以判断行动的方式是直行左拐还是右拐。
其实数据还应该进一步过滤一下,在路口附近的最近的点才作为起始点和终点。其实终点越远越准确,但是起始点决定了这次行为是否闯红灯。还可以进一步的按照一定限度去过滤。
1 import java.awt.image.DataBufferDouble; 2 import java.io.BufferedReader; 3 import java.io.File; 4 import java.io.FileReader; 5 import java.io.IOException; 6 import java.util.ArrayList; 7 import java.util.Collections; 8 import java.util.Comparator; 9 import java.util.HashSet; 10 import java.util.Iterator; 11 import java.util.LinkedList; 12 import java.util.List; 13 import java.util.Map; 14 import java.util.Set; 15 import java.util.Map.Entry; 16 import java.util.Scanner; 17 import java.util.stream.Collectors; 18 19 import org.eclipse.paho.client.mqttv3.MqttException; 20 import org.json.JSONException; 21 import org.json.JSONObject; 22 23 public class LambdaTest01 { 24 25 //决赛之前,一定把握坐标问题和时间戳问题的转换 26 27 28 // 测试路口的wgs坐标点,需要转换成最终bd坐标系才可以使用 29 public static final double InterSectionLat = 30.189142; 30 public static final double InterSectionLng = 120.191689; 31 // 测试路口的bd坐标系 32 public static double testInterSectionLat = 30.192505146716269; 33 public static double testInterSectionLng = 120.20282651800267; 34 // {"x":120.20282651800267,"y":30.192505146716269}]} 35 // // 决赛路口的bd坐标点,不需要转换就可以使用 36 public static final double finalinterSectionLat = 30.192811; 37 public static final double finalInterSectionLng = 120.213632; 38 // 相交前置条件 39 public static boolean x_collection = false; 40 public static boolean y_collection = false; 41 public static boolean xy_collection = false; 42 public static boolean yx_collection = false; 43 public static boolean red_green=false;//红灯true,路灯false 44 public static boolean stop_beyond=false;//等待为true,其他false, 45 public static int left_right=0;//左转-1,右转1,直行0 46 boolean test_or_final=true; 47 //测试数据路口红路灯数据 48 static long test1_1_timestamp=1538969853; 49 static int test1_1_greengap=34; 50 static int test1_1_redgap=86; 51 static long test2_1_timestamp=1538968687; 52 static int test2_1_greengap=86; 53 static int test2_1_redgap=34; 54 static long test3_1_timestamp=1538979847; 55 static int test3_1_greengap=22; 56 static int test3_1_redgap=98; 57 static long test4_1_timestamp=1538968653; 58 static int test4_1_greengap=34; 59 static int test4_1_redgap=86; 60 static long test5_1_timestamp=1538979869; 61 static int test5_1_greengap=98; 62 static int test5_1_redgap=22; 63 static long test6_1_timestamp=1538968653; 64 static int test6_1_greengap=34; 65 static int test6_1_redgap=86; 66 //决赛数据的路口红绿灯数据 67 68 /** 69 * 传递进去路径,解析json行并保存到arraylist中 70 * 71 * @param filelocation 72 * @return 73 * @throws JSONException 74 * @throws IOException 75 */ 76 @SuppressWarnings("resource") 77 public static List<ObjectProperty> file2ObjectList(String filelocation) throws JSONException, IOException { 78 79 File file = new File(filelocation); 80 // C:\\java_path\\workspace\\HelloWorld\\src\\iot.json 81 BufferedReader reader = null; 82 String temp = null; 83 int line = 1; 84 reader = new BufferedReader(new FileReader(file)); 85 List<ObjectProperty> objectProperties = new ArrayList<ObjectProperty>(); 86 while ((temp = reader.readLine()) != null) { 87 // System.out.println(line+":"+temp); 88 line++; 89 if (temp.equals("close") || temp.length() <= 20) 90 continue; 91 JSONObject my_json = new JSONObject(temp); 92 String devId = my_json.getString("devId"); 93 // System.out.println(devId); 94 long timestamp = my_json.getLong("timestamp"); 95 // System.out.println(timestamp); 96 double latitude = my_json.getDouble("latitude"); 97 // System.out.println(latitude); 98 double longitude = my_json.getDouble("longitude"); 99 // System.out.println(longitude); 100 int satellite = my_json.getInt("satellite"); 101 // System.out.println(satellite); 102 double hdop = my_json.getDouble("hdop"); 103 // System.out.println(hdop); 104 double altitude = my_json.getDouble("altitude"); 105 // System.out.println(altitude); 106 double speed = my_json.getDouble("speed"); 107 // System.out.println(speed); 108 double direction = my_json.getDouble("direction"); 109 // System.out.println(direction); 110 ObjectProperty e = new ObjectProperty(devId, timestamp, latitude, longitude, satellite, hdop, altitude, 111 speed, direction); 112 objectProperties.add(e); 113 } 114 return objectProperties; 115 } 116 117 /** 118 * 传递进去list对象,出来不重复的list对象 119 * 120 * @param objectProperties 121 * @return 122 */ 123 public static List<ObjectProperty> removeDuplicate(List<ObjectProperty> objectProperties) { 124 // 第一种方法,用contains方法循环去寻找 重写equals方法 125 // List tempList=new ArrayList(); 126 // for (ObjectProperty objectProperty : objectProperties) { 127 // if(!tempList.contains(objectProperty)) 128 // tempList.add(objectProperty); 129 // } 130 // return tempList; 131 // 第二种方法,使用set直接去hash去重 重写euqals和hashset方法 132 HashSet<ObjectProperty> hashSet = new HashSet<>(objectProperties); 133 objectProperties.clear(); 134 objectProperties.addAll(hashSet); 135 return objectProperties; 136 137 } 138 139 /** 140 * 传递list对象和devID得到其中符合条件的对象的个数 141 * 142 * @param objectProperties 143 * @param devID 144 * @return 145 */ 146 public static int ListCount(List<ObjectProperty> objectProperties, String devID) { 147 int count = 0; 148 for (ObjectProperty objectProperty : objectProperties) { 149 if (objectProperty.devId.equals(devID)) 150 count++; 151 } 152 return count; 153 } 154 155 /** 156 * 打印一下list中的元素 157 * 158 * @param objectProperties 159 */ 160 public static void print(List<ObjectProperty> objectProperties) { 161 for (ObjectProperty objectProperty : objectProperties) { 162 System.out.println(objectProperty.toString()); 163 } 164 } 165 166 /** 167 * 传递进去list对象,取出第一列对象作为list返回 168 * 169 * @param objectProperties 170 * @param Porperty 171 * @return 172 */ 173 public static List<String> findColume(List<ObjectProperty> objectProperties, String Porperty) { 174 List<String> neededList = new ArrayList<>(); 175 for (ObjectProperty objectProperty : objectProperties) { 176 if (Porperty.equals(Porperty)) 177 neededList.add(objectProperty.getDevId()); 178 } 179 return neededList; 180 } 181 182 public static List<ObjectProperty> no_stop(List<ObjectProperty> objectProperties) { 183 List<ObjectProperty> result = new ArrayList<>(); 184 for (ObjectProperty objectProperty : objectProperties) { 185 if (objectProperty.getSpeed() != 0) { 186 result.add(objectProperty); 187 } 188 } 189 return result; 190 } 191 192 /** 193 * 处理路口行为的主要算法 194 * @param id 195 * @param objectProperties 196 * @param i 197 * @throws IOException 198 */ 199 public static void MainAlgo(String id, List<ObjectProperty> objectProperties,int i) throws IOException { 200 System.out.println( 201 "================================当前的处理的devId是:" + id + "==========================================="); 202 System.out.println("当前的devId的点有这么多个:" + objectProperties.size()); 203 // objectProperties=no_stop(objectProperties); 204 // System.err.println("当前的devId运动的点有这么多个:"+objectProperties.size()); 205 System.out.println("首先进行按照timestamp的排序;"); 206 Collections.sort(objectProperties, Comparator.comparing(ObjectProperty::getTimestamp)); 207 System.out.println("排序完成后 ");System.out.println("当前的devId对应的各个点的属性:");print(objectProperties); 208 209 long start_time=objectProperties.get(0).getTimestamp(); 210 long stop_time=objectProperties.get(objectProperties.size()-1).getTimestamp(); 211 System.out.println("start_time="+start_time); 212 System.out.println("stop_time="+stop_time); 213 RedGreenClass redGreenClass=getCurrentCrossTimestamp(i); 214 long current_cross_timestamp=redGreenClass.getTimestamp(); 215 long red_gap=redGreenClass.getRed(); 216 long green_gap=redGreenClass.getGreed(); 217 if((start_time-current_cross_timestamp)%(red_gap+green_gap)<=green_gap) 218 red_green=false; 219 else if((start_time-current_cross_timestamp)%(red_gap+green_gap)>green_gap) 220 red_green=true; 221 long duration=stop_time-start_time; 222 System.out.println("经过路口的时长是:duration="+duration); 223 // long distance=current_cross_timestamp-start_time; 224 // System.out.println("当前路口距离红路灯开始的时间,负的才是正常的:distance="+distance); 225 226 227 /// 对一个对象的起始数据点进行操作 228 // 第一部分判断这个点是不是没动 229 // 第二部分,判断有没有过路行为 230 // 第三部分,分析往那个方向过的,左右,直,回三种情况 231 // 第四部分,结合红绿灯输出时候违规 232 System.out.println("----------------------------------"); 233 System.out.println("WGS坐标从第一个点到最后一个点的旋转角度:"); 234 double x1 = objectProperties.get(0).getLatitude(); 235 double y1 = objectProperties.get(0).getLongitude(); 236 double x2 = objectProperties.get(objectProperties.size() - 1).getLatitude(); 237 double y2 = objectProperties.get(objectProperties.size() - 1).getLongitude(); 238 System.out.println(y1 + "," + x1); 239 System.out.println(y2 + "," + x2); 240 double direction = DirectionClass.directionTurned(x1, y1, x2, y2); 241 boolean wise_reverse = DirectionClass.wise_anti(x1, y1, x2, y2); 242 System.out.println("旋转的角度" + direction); 243 244 System.out.println("BD坐标从第一个点到最后一个点的旋转角度:"); 245 Lon_Lat_Class c_start = BaiDuMapApi.FilterLocationFromResult(BaiDuMapApi.WGS2BD09(y1, x1)); 246 Lon_Lat_Class c_stop = BaiDuMapApi.FilterLocationFromResult(BaiDuMapApi.WGS2BD09(y2, x2)); 247 double x11 = c_start.getLatitude(); 248 double y11 = c_start.getLongitude(); 249 double x22 = c_stop.getLatitude(); 250 double y22 = c_stop.getLongitude(); 251 System.out.println(y11 + "," + x11); 252 System.out.println(y22 + "," + x22); 253 double direction_bd = DirectionClass.directionTurned_bd(x11, y11, x22, y22); 254 boolean wise_reverse_bd = DirectionClass.wise_anti_bd(x11, y11, x22, y22); 255 System.out.println("旋转的角度" + direction_bd); 256 257 System.out.println("***************************"); 258 boolean cross_or_not = lengthConvert.testIntersection(c_start, c_stop); 259 System.out.println("***************************"); 260 261 262 if (cross_or_not) { 263 // 发生了相交 264 stop_beyond=false;//不等待 265 if (direction_bd >= 45 && direction_bd <= 135) { 266 // 发生了转弯 267 if (wise_reverse_bd) { 268 left_right=-1; 269 System.out.println("向左转"); 270 } else if (!wise_reverse_bd) { 271 left_right=1; 272 System.out.println("向右转"); 273 } 274 } else if (direction_bd >= 135 && direction_bd <= 180) { 275 // 发生了直行行为 276 left_right=0; 277 System.out.println("直行"); 278 }else { 279 stop_beyond=true; 280 System.out.println("运动等待"); 281 } 282 } else if (!cross_or_not) { 283 // 没有相交,就是静止等待 284 stop_beyond=true; 285 System.out.println("等待"); 286 } 287 System.out.println("@@@总结如下:"); 288 if(stop_beyond) 289 System.out.println("当前对象等待"); 290 else { 291 if(red_green=false) { 292 System.out.println("当前对象红灯行为"); 293 if(left_right==-1) System.out.println("左拐"); 294 if(left_right==0) System.out.println("直行"); 295 if(left_right==1) System.out.println("右拐"); 296 }else if (red_green=true) 297 { 298 System.out.println("当前对象绿灯行为"); 299 if(left_right==-1) System.out.println("左拐"); 300 if(left_right==0) System.out.println("直行"); 301 if(left_right==1) System.out.println("右拐"); 302 } 303 } 304 System.out.println("================================当前的处理的devId是:" + id + "==========处理结束============================"); 305 306 // 将给出的wgs坐标转化为bd坐标 307 // Lon_Lat_Class 308 // lon_Lat_Class=BaiDuMapApi.FilterLocationFromResult(BaiDuMapApi.WGS2BD09(InterSectionLat, 309 // InterSectionLng)); 310 311 // 对一个对象中的所有的数据点进行过滤,暂时注销 312 // Lon_Lat_Class lon_Lat_Class=new 313 // Lon_Lat_Class(testInterSectionLng,testInterSectionLat); 314 // for (ObjectProperty objectProperty : objectProperties) { 315 // Lon_Lat_Class 316 // currentLocation=BaiDuMapApi.FilterLocationFromResult(BaiDuMapApi.WGS2BD09(objectProperty.getLongitude(), 317 // objectProperty.getLatitude())); 318 // Double currentLat=currentLocation.getLatitude(); 319 // Double currentLon=currentLocation.getLongitude(); 320 // Double CentralLat=lon_Lat_Class.getLatitude(); 321 // Double CentralLon=lon_Lat_Class.getLongitude(); 322 // Double dis2Intersection=lengthConvert.getDistance(CentralLat, CentralLon, 323 // currentLat, currentLon); 324 // System.out.println(CentralLon+","+CentralLat); 325 // System.out.println(currentLon+","+currentLat); 326 // System.out.println("计算两个坐标之间的差距是:"+dis2Intersection); 327 // } 328 // System.out.println(); 329 // 330 } 331 332 private static RedGreenClass getCurrentCrossTimestamp(int i) { 333 RedGreenClass redGreenClass=new RedGreenClass(); 334 if(i==1){ 335 redGreenClass.setTimestamp(test1_1_timestamp); 336 redGreenClass.setGreed(test1_1_greengap); 337 redGreenClass.setRed(test1_1_redgap); 338 } 339 if(i==2){ 340 redGreenClass.setTimestamp(test1_1_timestamp); 341 redGreenClass.setGreed(test2_1_greengap); 342 redGreenClass.setRed(test2_1_redgap); 343 } 344 if(i==3){ 345 redGreenClass.setTimestamp(test1_1_timestamp); 346 redGreenClass.setGreed(test3_1_greengap); 347 redGreenClass.setRed(test3_1_redgap); 348 } 349 if(i==4){ 350 redGreenClass.setTimestamp(test1_1_timestamp); 351 redGreenClass.setGreed(test4_1_greengap); 352 redGreenClass.setRed(test4_1_redgap); 353 } 354 if(i==5){ 355 redGreenClass.setTimestamp(test1_1_timestamp); 356 redGreenClass.setGreed(test5_1_greengap); 357 redGreenClass.setRed(test5_1_redgap); 358 } 359 if(i==6){ 360 redGreenClass.setTimestamp(test1_1_timestamp); 361 redGreenClass.setGreed(test6_1_greengap); 362 redGreenClass.setRed(test6_1_redgap); 363 } 364 return redGreenClass; 365 } 366 367 @SuppressWarnings({ "unused", "rawtypes", "unchecked" }) 368 public static void main(String[] args) throws IOException, MqttException, InterruptedException { 369 370 // List<ObjectProperty> 371 // objectProperties=file2ObjectList("C:\\java_path\\workspace\\HelloWorld\\src\\iot.json"); 372 Scanner scanner=new Scanner(System.in); 373 System.out.println("请输入是正式比赛:final还是测试的数据:test,之后按回车:"); 374 String test_final=scanner.nextLine(); 375 System.out.println("你的选择是:"+test_final); 376 System.out.println("请输入要测试的数据组数1-10中的数字选一个:"); 377 int i=scanner.nextInt(); 378 if(test_final.equals("final")) { 379 testInterSectionLat=finalinterSectionLat; 380 testInterSectionLng=finalInterSectionLng; 381 long test1_1_timestamp=1540000360; 382 int test1_1_greengap=82; 383 int test1_1_redgap=38; 384 long test2_1_timestamp=1540000360; 385 int test2_1_greengap=82; 386 int test2_1_redgap=38; 387 long test3_1_timestamp=1540000360; 388 int test3_1_greengap=82; 389 int test3_1_redgap=38; 390 long test4_1_timestamp=1540000360; 391 int test4_1_greengap=82; 392 int test4_1_redgap=38; 393 long test5_1_timestamp=1540000360; 394 int test5_1_greengap=82; 395 int test5_1_redgap=38; 396 long test6_1_timestamp=1540000360; 397 int test6_1_greengap=38; 398 int test6_1_redgap=82; 399 400 401 } 402 403 long time=System.currentTimeMillis()/1000; 404 System.out.println("---从mqtt端订阅一个主题---"); 405 MQTT_Client_Receive.Topics2Files(i, test_final,time); 406 407 String location="D:\\"+i+"_"+time+".json"; 408 System.out.println("---从文件"+location+"创建一个list---"); 409 List<ObjectProperty> objectProperties = file2ObjectList(location); 410 // System.out.print("---包含指定性质CD8ADC41元素的list的数目:"); 411 // System.out.println(ListCount(objectProperties, "CD8ADC41")); 412 413 System.out.println(); 414 System.out.println("---当前文件中包含的数据的条目个数为:" + objectProperties.size() + "---"); 415 System.out.println("---删除list中重复的元素---"); 416 objectProperties = removeDuplicate(objectProperties); 417 System.out.println("---删除list中重复的元素完成---"); 418 System.out.println("---当前文件中包含的数据的条目的个数为:" + objectProperties.size() + "---"); 419 System.out.println(); 420 // 将取出的数据按照id进行分开 421 Map<String, List<ObjectProperty>> groupBy = objectProperties.stream() 422 .collect(Collectors.groupingBy(ObjectProperty::getDevId)); 423 System.out.println("----当前文件中的对象有多少个" + groupBy.keySet().size() + "---"); 424 425 if(i<=6) { 426 System.out.println("处理红路灯"); 427 GreenRedProcess(); 428 } 429 430 Set set = groupBy.entrySet(); 431 for (Iterator iterator = set.iterator(); iterator.hasNext();) { 432 Map.Entry entry = (Entry) iterator.next(); 433 if(i<=6) { 434 MainAlgo((String) entry.getKey(), (List<ObjectProperty>) entry.getValue(),i);// 调用路口行为主要的处理函数 435 // System.out.println(entry.getKey()+"->"+entry.getValue()); 436 }else if(i==7||i==8) { 437 MainAlgoForHight((String)entry.getKey(),(List<ObjectProperty>)entry.getValue(),i); 438 }else if(i==9||i==10) { 439 MainAlgoForDrawMap((String)entry.getKey(),(List<ObjectProperty>)entry.getValue(),i); 440 } 441 } 442 443 // System.out.println(groupBy); 444 // 单独把第一列拉出来 445 List<String> firstList = findColume(objectProperties, "devId"); 446 // firstList.stream().collect(Collectors.groupingBy(firstList.)) 447 448 // System.out.print("---包含指定性质CD8ADC41元素的list的数目:"); 449 // System.out.println(ListCount(objectProperties, "CD8ADC41")); 450 // System.out.print("---包含指定性质CD8ADC42元素的list的数目:"); 451 // System.out.println(ListCount(objectProperties, "CD8ADC42")); 452 453 } 454 455 private static void MainAlgoForDrawMap(String id, List<ObjectProperty> objectProperties,int i) { 456 457 } 458 459 private static void MainAlgoForHight(String id, List<ObjectProperty> objectProperties,int i) { 460 System.out.println("================================当前的处理的devId是:" + id + "==========================================="); 461 System.out.println("当前的devId的点有这么多个:" + objectProperties.size()); 462 // objectProperties=no_stop(objectProperties); 463 // System.err.println("当前的devId运动的点有这么多个:"+objectProperties.size()); 464 System.out.println("首先进行按照timestamp的排序;"); 465 Collections.sort(objectProperties, Comparator.comparing(ObjectProperty::getTimestamp)); 466 System.out.println("排序完成后 ");System.out.println("当前的devId对应的各个点的属性:");print(objectProperties); 467 468 469 } 470 471 private static void GreenRedProcess() { 472 473 } 474 475 }
万事走心 精益求美