/* * Copyright 2009 Olivier LIECHTI <olivier.liechti@heig-vd.ch>. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * under the License. */ package com.ubike.processor; import com.ubike.model.TrackPoint; import com.ubike.model.Trip; import com.ubike.services.TripManagerLocal; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.Date; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; import javax.ejb.EJB; /** * * @author oliechti * http://eppleton.sharedhost.de/blog/?p=142 */ public class NMEAFileProcessor implements FileProcessor { @EJB private TripManagerLocal tripManager; private List<TrackPoint> trackPoints = new LinkedList<TrackPoint>(); private double totalDistance = 0.0; private Date startTime = null; private Date endTime = null; private long totalTime = 0; public void processFile(File inputFile, NMEAFileProcessorContext context) { Map<String, String> readValues = new HashMap<String, String>(); Set<String> readSentences = new HashSet<String>(); TrackPoint marker = null; try { BufferedReader br = new BufferedReader(new FileReader(inputFile)); String line = br.readLine(); while (line != null) { String[] fields = line.split(","); if (fields.length == 0) { line = br.readLine(); continue; } String recordType = fields[0]; // we are reading a new record if (readSentences.contains(recordType)) { processTrackPoint(readValues); if (trackPoints.size() > 3) { TrackPoint tp = trackPoints.get(trackPoints.size() - 1); TrackPoint previousTrackPoint = trackPoints.get(trackPoints.size() - 2); if (Math.abs(tp.getTimestamp() - previousTrackPoint.getTimestamp()) > 10 * 60 * 1000) { if (marker == null) marker = trackPoints.get(0); long tripStartTime = marker.getTimestamp(); long tripEndTime = tp.getTimestamp(); // TODO verify code !!! //Trip trip = new Trip(new Date(tripStartTime), new Date(tripEndTime), totalDistance, trackPoints); Trip trip = new Trip(); trip.setStartDate(new Date(tripStartTime)); trip.setEndDate(new Date(tripEndTime)); trip.setDistance(totalDistance); trackPoints.remove(tp); context.addTrip(trip); marker = tp; trackPoints = new LinkedList<TrackPoint>(); totalDistance = 0; } } readValues.clear(); readSentences.clear(); } if (recordType.equals("$GPGGA")) { readSentences.add("$GPGGA"); readValues.put("time", fields[1]); readValues.put("latitude", fields[2] + "," + fields[3]); readValues.put("longitude", fields[4] + "," + fields[5]); readValues.put("fixQuality", fields[6]); readValues.put("numberOfSatellites", fields[7]); readValues.put("altitude", fields[9]); } else if (recordType.equals("$GPRMC")) { readSentences.add("$GPRMC"); readValues.put("time", fields[1]); readValues.put("latitude", fields[3] + "," + fields[4]); readValues.put("longitude", fields[5] + "," + fields[6]); readValues.put("speedKnot", fields[7]); readValues.put("date", fields[9]); } else if (recordType.equals("$GPVTG")) { readSentences.add("$GPVTG"); readValues.put("speedKnot", fields[5]); readValues.put("speedKmh", fields[7]); } line = br.readLine(); } if (trackPoints.size() > 2) { long tripStartTime = trackPoints.get(0).getTimestamp(); long tripEndTime = trackPoints.get(trackPoints.size() - 1).getTimestamp(); // TODO verify the following code !!! //Trip trip = new Trip(tripStartTime, tripEndTime, totalDistance, trackPoints); Trip trip = new Trip(); trip.setStartDate(new Date(tripStartTime)); trip.setEndDate(new Date(tripEndTime)); trip.setDistance(totalDistance); context.addTrip(trip); } //System.out.println("Total trip distance: " + totalDistance); //System.out.println("Total trip time : " + (nmeaTimeToMillis(lastTime) - nmeaTimeToMillis(startTime))); //System.out.println("Start time: " + new Date(trackPoints.get(0).getTimestamp())); //System.out.println("End time : " + new Date(trackPoints.get(trackPoints.size()-1).getTimestamp())); } catch (IOException ex) { Logger.getLogger(NMEAFileProcessor.class.getName()).log(Level.SEVERE, null, ex); } } private void processTrackPoint(Map<String, String> readValues) { //System.out.println(readValues); try { TrackPoint tp = new TrackPoint(); /** tp.setFixQuality(Integer.parseInt(readValues.get("fixQuality"))); if (tp.getFixQuality() == 0) { return; } */ double latitude = nmeaToDeg(readValues.get("latitude")); double longitude = nmeaToDeg(readValues.get("longitude")); double altitude = Double.parseDouble(readValues.get("altitude")); //tp.setLatitude(latitude); tp.getGpsCoord().setLatitude(latitude); //tp.setLongitude(longitude); tp.getGpsCoord().setLongitude(longitude); //tp.setAltitude(altitude); tp.getGpsCoord().setAltitude(altitude); //tp.setNumberOfSatellites(Integer.parseInt(readValues.get("numberOfSatellites"))); tp.setTimestamp(nmeaDateTimeToMillis(readValues.get("date") + readValues.get("time"))); // 1 knot = 1.852 km/h //tp.setSpeed(Double.parseDouble(readValues.get("speedKnot")) * 1.852); if (trackPoints.size() > 1) { TrackPoint previousTrackPoint = trackPoints.get(trackPoints.size() - 1); double relativeDistance = previousTrackPoint.distanceTo(tp); totalDistance += relativeDistance; } trackPoints.add(tp); } catch (Exception e) { System.out.println("Error processing trackpoint: " + e.getMessage()); } } private long nmeaDateTimeToMillis(String nmeaDateTime) { int day = Integer.parseInt(nmeaDateTime.substring(0, 2)); int month = Integer.parseInt(nmeaDateTime.substring(2, 4)); int year = 100 + Integer.parseInt(nmeaDateTime.substring(4, 6)); int hour = Integer.parseInt(nmeaDateTime.substring(6, 8)); int min = Integer.parseInt(nmeaDateTime.substring(8, 10)); int sec = Integer.parseInt(nmeaDateTime.substring(10, 12)); Date date = new Date(year, month, day, hour, min, sec); return date.getTime(); } private long nmeaTimeToMillis(String nmeaTime) { int hour = Integer.parseInt(nmeaTime.substring(0, 2)); int min = Integer.parseInt(nmeaTime.substring(2, 4)); int sec = Integer.parseInt(nmeaTime.substring(4, 6)); Date date = new Date(1970, 1, 1, hour, min, sec); return date.getTime(); } private double nmeaToDeg(String latitudeOrLongitude) { String[] fields = latitudeOrLongitude.split(","); double value = Double.parseDouble(fields[0]); String hemisphere = fields[1]; int latAngle = (int) (value / 100); double latMin = (value - (100 * latAngle)) / 60; double result = latAngle + latMin; if (hemisphere.equals("S") || hemisphere.equals("W")) { result = result * -1; } return result; } public void processFile(File inputFile, FileProcessorContext context) { throw new UnsupportedOperationException("Not supported yet."); } }