@SuppressWarnings("unchecked") @ApiMethod(name = "checkTrainAndStationStatus", path = "findmytrain/v1/checkStatus") public List<String> checkTrainAndStationStatus( @Named("Train id") String id, @Named("Currnet Station") String station) { // this method returns the list of stations for a selected train and // whether that train has passed each station final int STATION_GAP = 5; // five station from the current station to // both directions are considered for the // calculation final int RECORD_THRESHOLD = 10; final double PROBABILITY_THRESHOLD_LEFT = 0.65; final double PROBABILITY_THRESHOLD_NOT_LEFT = 0.35; final double TRANSITION_THRESHOLD = 0.2; final int RECORD_CONSIDERATION_LIMIT_NUMBER = 50; final int RECORD_CONSIDERATION_LIMIT_MINUTES = 30; // this value can be // reduced when the // number of users // become // higher.(since // there will be // more data to // analyze with in // the given time // period) final long ONE_MINUTE_IN_MILLIS = 60000; List<String> result = new ArrayList<String>(); List<Train> trains = new ArrayList<Train>(); List<Record> records = new ArrayList<Record>(); PersistenceManager pm = PMF.get().getPersistenceManager(); Query queryTrain = pm.newQuery(Train.class); queryTrain.setFilter("trainid == argTrainId"); queryTrain.declareParameters("String argTrainId"); Query queryRecord = pm.newQuery(Record.class); queryTrain.setFilter("trainid == argTrainId"); queryTrain.declareParameters("String argTrainId"); trains = (List<Train>) queryTrain.execute(id); records = (List<Record>) queryRecord.execute(id); List<Stop> stops = new ArrayList<Stop>(); List<Record> tempRecords; int stationIndex = 0; int initialOneCount; int initialZeroCount; double probabilityInitial; double probabilityTransition; int[] centralDifference; int transitionCount; Date atRequest = new Date(); SimpleDateFormat parser = new SimpleDateFormat("HH:mm"); String serverTime = parser.format(atRequest); Date serverDate = null; Date lowerLimit = null; try { serverDate = parser.parse(serverTime); lowerLimit = new Date( serverDate.getTime() - (RECORD_CONSIDERATION_LIMIT_MINUTES * ONE_MINUTE_IN_MILLIS)); } catch (ParseException e) { e.printStackTrace(); } stops = trains.get(0).getStops(); for (int i = 0; i < stops.size(); i++) { if (stops.get(i).getStation().equals(station)) stationIndex = i; } int loopStart = stationIndex >= STATION_GAP ? stationIndex - STATION_GAP : 0; int loopEnd = stationIndex + STATION_GAP < stops.size() ? stationIndex + STATION_GAP : stops.size(); for (int i = loopStart; i < loopEnd; i++) { Stop tempStop = stops.get(i); String tempStatus = "not sure"; // for the situation where there are // not enough data present tempRecords = new ArrayList<Record>(); // these are the records used // to process the data for // each selected station initialOneCount = 0; initialZeroCount = 0; for (Record r : records) { if (r.getStation().equals(tempStop.getStation())) { tempRecords.add(r); } } // case where there is no data if (tempRecords.size() < RECORD_THRESHOLD) { result.add(tempStop.getStation() + ":" + tempStatus); continue; } // when there is enough data sortRecords(tempRecords); // selecting a set of record to perform the analysis based on their // recentness and the number of records int k = 0; for (int j = 0; j < tempRecords.size(); j++) { Date tempDate = new Date(tempRecords.get(j).getTimeStamp()); String tempTime = parser.format(tempDate); try { Date recordDate = parser.parse(tempTime); if (recordDate.after(lowerLimit)) { k = j; break; } } catch (ParseException e) { e.printStackTrace(); } } if (tempRecords.size() - k < RECORD_CONSIDERATION_LIMIT_NUMBER) { if (tempRecords.size() < RECORD_CONSIDERATION_LIMIT_NUMBER) { k = 0; } else k = tempRecords.size() - RECORD_CONSIDERATION_LIMIT_NUMBER; } for (int j = k; j < tempRecords.size(); j++) { // counting the initial ones and zeros System.out.print(j + " "); if (tempRecords.get(j).getStatus() == 1) initialOneCount++; else initialZeroCount++; } System.out.println(); probabilityInitial = (double) initialOneCount / (tempRecords.size()); if (probabilityInitial > PROBABILITY_THRESHOLD_LEFT) { tempStatus = "left"; } else if (probabilityInitial < PROBABILITY_THRESHOLD_NOT_LEFT) { tempStatus = "not left"; } else { // using the first central difference formula centralDifference = new int[tempRecords.size() - 1]; for (int j = 1; j < tempRecords.size(); j++) { centralDifference[j - 1] = tempRecords.get(j).getStatus() - tempRecords.get(j - 1).getStatus(); } transitionCount = 0; for (int j : centralDifference) { if (j == 1) transitionCount++; } probabilityTransition = (double) transitionCount / centralDifference.length; if (probabilityTransition < TRANSITION_THRESHOLD) { tempStatus = "left"; } else { tempStatus = "not sure"; } } // at this point data can be further checked to refine the results result.add(tempStop.getStation() + ":" + tempStatus); } return result; }
@SuppressWarnings("unchecked") @ApiMethod(name = "listOfTrains", path = "findmytrain/v1/listTrains") public List<String> listTrains(@Named("station") String station) throws ParseException { // This method should return the list of trains based on the station // if a trains stops at the station 'station' that will be added to the // 'trains' list final long ONE_MINUTE_IN_MILLIS = 60000; final int TIME_GAP_IN_MINUTES = 30; List<Train> trains = new ArrayList<Train>(); List<Train> tempTrains = null; Date atRequest = new Date(); SimpleDateFormat parser = new SimpleDateFormat("HH:mm"); String serverTime = parser.format(atRequest); Date serverDate = parser.parse(serverTime); Date upperLimit = new Date(serverDate.getTime() + (TIME_GAP_IN_MINUTES * ONE_MINUTE_IN_MILLIS)); Date lowerLimit = new Date(serverDate.getTime() - (TIME_GAP_IN_MINUTES * ONE_MINUTE_IN_MILLIS)); // System.out.println("Server date : " + serverDate); // System.out.println("Server time : " + serverTime); PersistenceManager pm = PMF.get().getPersistenceManager(); Query q = pm.newQuery(Train.class); try { tempTrains = (List<Train>) q.execute(); List<Stop> tempStops = new ArrayList<Stop>(); for (Train t : tempTrains) { tempStops = t.getStops(); for (Stop s : tempStops) { // checking if a selected train stops at the selected // station if (s.getStation().equals(station)) { Date stationTime = parser.parse(s.getTime()); // checking whether the station time is in between the // required time gap if (stationTime.after(lowerLimit) && stationTime.before(upperLimit)) { trains.add(t); break; } } } } } finally { q.closeAll(); } // returning a string list instead of the train list List<String> result = new ArrayList<String>(); for (Train t : trains) { result.add("From " + t.getStart() + " To " + t.getDestination() + "\n" + t.getTrainid()); } return result; // returning the list of train objects // return trains; }