給定一些json數據,是電動車的行爲數據。主要是GPS相關的數據。java
例如:git
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}
給定一個紅綠燈,讓判斷這個數據中包含的小車對象在路口的行爲是等待仍是行動,行動的話第一是否是闖紅燈,第二闖紅燈是左拐仍是右拐仍是直行。算法
另外兩個問題是上高架和畫軌跡的問題,在高架上和下目前主要是經過精確的高度過濾獲得。畫圖主要是上傳到百度的鷹視裏面去看一下基本的軌跡。略微實現了一點點的綁路的擬合。json
可是重點是路口行爲的判斷。拿到數據以後首先過濾一下重複的數據,而後找到同一個對象的數據,而後按照時間序列拍一下隊。eclipse
其次根據路口座標就能夠用三角函數判斷旋轉的角度和方向。輔助的話還設定四個線段。以路口爲中心,左右方向,上下方向和斜着的兩個方向。函數
若是移動軌跡和這四條有限長度的線段有相交的話也是能夠判斷行動的方式是直行左拐仍是右拐。測試
其實數據還應該進一步過濾一下,在路口附近的最近的點才做爲起始點和終點。其實終點越遠越準確,可是起始點決定了此次行爲是否闖紅燈。還能夠進一步的按照必定限度去過濾。spa
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 }