forked from upstream-mirrors/OpenTracks
code format
This commit is contained in:
@@ -950,46 +950,46 @@ public class MyTracks extends TabActivity implements OnTouchListener,
|
||||
showDialogSafely(DIALOG_IMPORT_PROGRESS);
|
||||
Thread t = new Thread() {
|
||||
@Override
|
||||
public void run() {
|
||||
int message = R.string.success;
|
||||
public void run() {
|
||||
int message = R.string.success;
|
||||
|
||||
long[] trackIdsImported = null;
|
||||
long[] trackIdsImported = null;
|
||||
|
||||
try {
|
||||
try {
|
||||
InputStream is = new FileInputStream(fileName);
|
||||
trackIdsImported = GpxSaxImporter.importGPXFile(is, providerUtils);
|
||||
} catch (SAXException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
|
||||
message = R.string.error_generic;
|
||||
} catch (ParserConfigurationException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
|
||||
message = R.string.error_generic;
|
||||
} catch (IOException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
|
||||
message = R.string.error_unable_to_read_file;
|
||||
} catch (NullPointerException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
|
||||
message = R.string.error_invalid_gpx_format;
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
|
||||
message = R.string.error_out_of_memory;
|
||||
}
|
||||
if (trackIdsImported != null && trackIdsImported.length > 0) {
|
||||
// select last track from import file
|
||||
setSelectedTrack(trackIdsImported[trackIdsImported.length - 1]);
|
||||
} else {
|
||||
MyTracks.this.showMessageDialog(message, false/* success */);
|
||||
}
|
||||
} finally {
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
dismissDialog(DIALOG_IMPORT_PROGRESS);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
try {
|
||||
try {
|
||||
InputStream is = new FileInputStream(fileName);
|
||||
trackIdsImported = GpxSaxImporter.importGPXFile(is, providerUtils);
|
||||
} catch (SAXException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
|
||||
message = R.string.error_generic;
|
||||
} catch (ParserConfigurationException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
|
||||
message = R.string.error_generic;
|
||||
} catch (IOException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
|
||||
message = R.string.error_unable_to_read_file;
|
||||
} catch (NullPointerException e) {
|
||||
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
|
||||
message = R.string.error_invalid_gpx_format;
|
||||
} catch (OutOfMemoryError e) {
|
||||
Log.e(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
|
||||
message = R.string.error_out_of_memory;
|
||||
}
|
||||
if (trackIdsImported != null && trackIdsImported.length > 0) {
|
||||
// select last track from import file
|
||||
setSelectedTrack(trackIdsImported[trackIdsImported.length - 1]);
|
||||
} else {
|
||||
MyTracks.this.showMessageDialog(message, false/* success */);
|
||||
}
|
||||
} finally {
|
||||
runOnUiThread(new Runnable() {
|
||||
public void run() {
|
||||
dismissDialog(DIALOG_IMPORT_PROGRESS);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
t.start();
|
||||
}
|
||||
|
||||
|
||||
@@ -47,384 +47,384 @@ import com.google.android.apps.mytracks.util.MyTracksUtils;
|
||||
*/
|
||||
public class GpxSaxImporter extends DefaultHandler {
|
||||
|
||||
/**
|
||||
* Different data formats used in GPX files
|
||||
*/
|
||||
private static final SimpleDateFormat DATE_FORMAT1 = new SimpleDateFormat(
|
||||
"yyyy-MM-dd'T'hh:mm:ssZ");
|
||||
private static final SimpleDateFormat DATE_FORMAT2 = new SimpleDateFormat(
|
||||
"yyyy-MM-dd'T'hh:mm:ss'Z'");
|
||||
private static final SimpleDateFormat DATE_FORMAT3 = new SimpleDateFormat(
|
||||
"yyyy-MM-dd'T'HH:mm:ss.SSSZ");
|
||||
/**
|
||||
* Different data formats used in GPX files
|
||||
*/
|
||||
private static final SimpleDateFormat DATE_FORMAT1 = new SimpleDateFormat(
|
||||
"yyyy-MM-dd'T'hh:mm:ssZ");
|
||||
private static final SimpleDateFormat DATE_FORMAT2 = new SimpleDateFormat(
|
||||
"yyyy-MM-dd'T'hh:mm:ss'Z'");
|
||||
private static final SimpleDateFormat DATE_FORMAT3 = new SimpleDateFormat(
|
||||
"yyyy-MM-dd'T'HH:mm:ss.SSSZ");
|
||||
|
||||
/**
|
||||
* GPX-XML tag names and attributes
|
||||
*/
|
||||
private static final String TAG_TRACK = "trk";
|
||||
private static final String TAG_TRACK_POINT = "trkpt";
|
||||
private static final String TAG_NAME = "name";
|
||||
private static final String TAG_DESCRIPTION = "desc";
|
||||
private static final String TAG_ALTITUDE = "ele";
|
||||
private static final String TAG_TIME = "time";
|
||||
private static final String ATT_LAT = "lat";
|
||||
private static final String ATT_LON = "lon";
|
||||
/**
|
||||
* GPX-XML tag names and attributes
|
||||
*/
|
||||
private static final String TAG_TRACK = "trk";
|
||||
private static final String TAG_TRACK_POINT = "trkpt";
|
||||
private static final String TAG_NAME = "name";
|
||||
private static final String TAG_DESCRIPTION = "desc";
|
||||
private static final String TAG_ALTITUDE = "ele";
|
||||
private static final String TAG_TIME = "time";
|
||||
private static final String ATT_LAT = "lat";
|
||||
private static final String ATT_LON = "lon";
|
||||
|
||||
/**
|
||||
* Contains the current elements content
|
||||
*/
|
||||
private StringBuilder content;
|
||||
/**
|
||||
* Contains the current elements content
|
||||
*/
|
||||
private StringBuilder content;
|
||||
|
||||
/**
|
||||
* Currently reading location
|
||||
*/
|
||||
private Location location;
|
||||
/**
|
||||
* Currently reading location
|
||||
*/
|
||||
private Location location;
|
||||
|
||||
/**
|
||||
* Previous location, required for calculations
|
||||
*/
|
||||
private Location lastLocation;
|
||||
/**
|
||||
* Previous location, required for calculations
|
||||
*/
|
||||
private Location lastLocation;
|
||||
|
||||
/**
|
||||
* Currently reading track
|
||||
*/
|
||||
private Track track;
|
||||
/**
|
||||
* Currently reading track
|
||||
*/
|
||||
private Track track;
|
||||
|
||||
/**
|
||||
* Statistics object for the current track
|
||||
*/
|
||||
private TripStatistics stats;
|
||||
/**
|
||||
* Statistics object for the current track
|
||||
*/
|
||||
private TripStatistics stats;
|
||||
|
||||
/**
|
||||
* Number of locations already processed
|
||||
*/
|
||||
private int numberOfLocations;
|
||||
/**
|
||||
* Number of locations already processed
|
||||
*/
|
||||
private int numberOfLocations;
|
||||
|
||||
/**
|
||||
* List of track ids written in the database does only contain successful
|
||||
* finished ones
|
||||
*/
|
||||
private List<Long> tracksWritten;
|
||||
/**
|
||||
* List of track ids written in the database does only contain successful
|
||||
* finished ones
|
||||
*/
|
||||
private List<Long> tracksWritten;
|
||||
|
||||
/**
|
||||
* used to identify if a track was written to the database but not yet finish
|
||||
* successfully
|
||||
*/
|
||||
private boolean isCurrentTrackRollbackable;
|
||||
/**
|
||||
* used to identify if a track was written to the database but not yet finish
|
||||
* successfully
|
||||
*/
|
||||
private boolean isCurrentTrackRollbackable;
|
||||
|
||||
private MyTracksProviderUtils providerUtils;
|
||||
private MyTracksProviderUtils providerUtils;
|
||||
|
||||
/**
|
||||
* flag to indicate if we in a track xml element some sub elements like name
|
||||
* may be used in other parts of the gpx file - ignore them
|
||||
*/
|
||||
private boolean isInTrackElement;
|
||||
/**
|
||||
* flag to indicate if we in a track xml element some sub elements like name
|
||||
* may be used in other parts of the gpx file - ignore them
|
||||
*/
|
||||
private boolean isInTrackElement;
|
||||
|
||||
/**
|
||||
* Reads GPS tracks from a GPX file and append tracks and their coordinates to
|
||||
* the given list of tracks.
|
||||
*
|
||||
* Callers must execute
|
||||
*
|
||||
* <pre>
|
||||
* rollbackUnfinishedTrack
|
||||
* </pre>
|
||||
*
|
||||
* in case of an exception to avoid inconsistent data
|
||||
*
|
||||
* @param tracks
|
||||
* a list of tracks
|
||||
* @param is
|
||||
* a input steam with gpx-xml data
|
||||
* @throws SAXException
|
||||
* a parsing error
|
||||
* @throws ParserConfigurationException
|
||||
* internal error
|
||||
* @throws IOException
|
||||
* a file reading problem
|
||||
*/
|
||||
public static long[] importGPXFile(final InputStream is,
|
||||
final MyTracksProviderUtils providerUtils)
|
||||
throws ParserConfigurationException, SAXException, IOException {
|
||||
/**
|
||||
* Reads GPS tracks from a GPX file and append tracks and their coordinates to
|
||||
* the given list of tracks.
|
||||
*
|
||||
* Callers must execute
|
||||
*
|
||||
* <pre>
|
||||
* rollbackUnfinishedTrack
|
||||
* </pre>
|
||||
*
|
||||
* in case of an exception to avoid inconsistent data
|
||||
*
|
||||
* @param tracks
|
||||
* a list of tracks
|
||||
* @param is
|
||||
* a input steam with gpx-xml data
|
||||
* @throws SAXException
|
||||
* a parsing error
|
||||
* @throws ParserConfigurationException
|
||||
* internal error
|
||||
* @throws IOException
|
||||
* a file reading problem
|
||||
*/
|
||||
public static long[] importGPXFile(final InputStream is,
|
||||
final MyTracksProviderUtils providerUtils)
|
||||
throws ParserConfigurationException, SAXException, IOException {
|
||||
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
GpxSaxImporter handler = new GpxSaxImporter(providerUtils);
|
||||
SAXParser parser = factory.newSAXParser();
|
||||
long[] trackIds = null;
|
||||
SAXParserFactory factory = SAXParserFactory.newInstance();
|
||||
GpxSaxImporter handler = new GpxSaxImporter(providerUtils);
|
||||
SAXParser parser = factory.newSAXParser();
|
||||
long[] trackIds = null;
|
||||
|
||||
try {
|
||||
parser.parse(is, handler);
|
||||
trackIds = handler.getImportedTrackIds();
|
||||
} finally {
|
||||
// delete track if not finished
|
||||
handler.rollbackUnfinishedTracks();
|
||||
}
|
||||
try {
|
||||
parser.parse(is, handler);
|
||||
trackIds = handler.getImportedTrackIds();
|
||||
} finally {
|
||||
// delete track if not finished
|
||||
handler.rollbackUnfinishedTracks();
|
||||
}
|
||||
|
||||
return trackIds;
|
||||
}
|
||||
return trackIds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor, requires providerUtils for writing tracks the database.
|
||||
*/
|
||||
public GpxSaxImporter(MyTracksProviderUtils providerUtils) {
|
||||
this.providerUtils = providerUtils;
|
||||
tracksWritten = new ArrayList<Long>();
|
||||
content = new StringBuilder();
|
||||
}
|
||||
/**
|
||||
* Constructor, requires providerUtils for writing tracks the database.
|
||||
*/
|
||||
public GpxSaxImporter(MyTracksProviderUtils providerUtils) {
|
||||
this.providerUtils = providerUtils;
|
||||
tracksWritten = new ArrayList<Long>();
|
||||
content = new StringBuilder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
content.append(ch, start, length);
|
||||
}
|
||||
@Override
|
||||
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||
content.append(ch, start, length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String name,
|
||||
Attributes attributes) throws SAXException {
|
||||
@Override
|
||||
public void startElement(String uri, String localName, String name,
|
||||
Attributes attributes) throws SAXException {
|
||||
|
||||
if (localName.equalsIgnoreCase(TAG_TRACK)) {
|
||||
isInTrackElement = true;
|
||||
onTrackElementStart();
|
||||
if (localName.equalsIgnoreCase(TAG_TRACK)) {
|
||||
isInTrackElement = true;
|
||||
onTrackElementStart();
|
||||
|
||||
// process this element only as sub-elements of track
|
||||
} else if (isInTrackElement) {
|
||||
// process this element only as sub-elements of track
|
||||
} else if (isInTrackElement) {
|
||||
|
||||
if (localName.equalsIgnoreCase(TAG_TRACK_POINT)) {
|
||||
onTrackPointElementStart(attributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (localName.equalsIgnoreCase(TAG_TRACK_POINT)) {
|
||||
onTrackPointElementStart(attributes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endElement(String uri, String localName, String name)
|
||||
throws SAXException {
|
||||
@Override
|
||||
public void endElement(String uri, String localName, String name)
|
||||
throws SAXException {
|
||||
|
||||
if (localName.equalsIgnoreCase(TAG_TRACK)) {
|
||||
onTrackElementEnd();
|
||||
isInTrackElement = false;
|
||||
if (localName.equalsIgnoreCase(TAG_TRACK)) {
|
||||
onTrackElementEnd();
|
||||
isInTrackElement = false;
|
||||
|
||||
// process these elements only as sub-elements of track
|
||||
} else if (isInTrackElement) {
|
||||
// process these elements only as sub-elements of track
|
||||
} else if (isInTrackElement) {
|
||||
|
||||
if (localName.equalsIgnoreCase(TAG_TRACK_POINT)) {
|
||||
onTrackPointElementEnd();
|
||||
} else if (localName.equalsIgnoreCase(TAG_ALTITUDE)) {
|
||||
onAltitudeElementEnd();
|
||||
} else if (localName.equalsIgnoreCase(TAG_TIME)) {
|
||||
onTimeElementEnd();
|
||||
} else if (localName.equalsIgnoreCase(TAG_NAME)) {
|
||||
onNameElementEnd();
|
||||
} else if (localName.equalsIgnoreCase(TAG_DESCRIPTION)) {
|
||||
onDescriptionElementEnd();
|
||||
}
|
||||
}
|
||||
if (localName.equalsIgnoreCase(TAG_TRACK_POINT)) {
|
||||
onTrackPointElementEnd();
|
||||
} else if (localName.equalsIgnoreCase(TAG_ALTITUDE)) {
|
||||
onAltitudeElementEnd();
|
||||
} else if (localName.equalsIgnoreCase(TAG_TIME)) {
|
||||
onTimeElementEnd();
|
||||
} else if (localName.equalsIgnoreCase(TAG_NAME)) {
|
||||
onNameElementEnd();
|
||||
} else if (localName.equalsIgnoreCase(TAG_DESCRIPTION)) {
|
||||
onDescriptionElementEnd();
|
||||
}
|
||||
}
|
||||
|
||||
// reset element content
|
||||
content.setLength(0);
|
||||
}
|
||||
// reset element content
|
||||
content.setLength(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Track object and insert empty track in database. Track will be
|
||||
* updated with missing values later.
|
||||
*/
|
||||
private void onTrackElementStart() {
|
||||
/**
|
||||
* Create a new Track object and insert empty track in database. Track will be
|
||||
* updated with missing values later.
|
||||
*/
|
||||
private void onTrackElementStart() {
|
||||
|
||||
track = new Track();
|
||||
numberOfLocations = 0;
|
||||
track = new Track();
|
||||
numberOfLocations = 0;
|
||||
|
||||
Uri trackUri = providerUtils.insertTrack(track);
|
||||
long trackId = Long.parseLong(trackUri.getLastPathSegment());
|
||||
track.setId(trackId);
|
||||
isCurrentTrackRollbackable = true;
|
||||
}
|
||||
Uri trackUri = providerUtils.insertTrack(track);
|
||||
long trackId = Long.parseLong(trackUri.getLastPathSegment());
|
||||
track.setId(trackId);
|
||||
isCurrentTrackRollbackable = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads trackpoint attributes and assigns them to the current location
|
||||
*
|
||||
* @param attributes
|
||||
* xml attributes
|
||||
*/
|
||||
private void onTrackPointElementStart(Attributes attributes) {
|
||||
location = createLocationFromAttributes(attributes);
|
||||
}
|
||||
/**
|
||||
* Reads trackpoint attributes and assigns them to the current location
|
||||
*
|
||||
* @param attributes
|
||||
* xml attributes
|
||||
*/
|
||||
private void onTrackPointElementStart(Attributes attributes) {
|
||||
location = createLocationFromAttributes(attributes);
|
||||
}
|
||||
|
||||
private Location createLocationFromAttributes(Attributes attributes) {
|
||||
String latitude = null;
|
||||
String longitude = null;
|
||||
private Location createLocationFromAttributes(Attributes attributes) {
|
||||
String latitude = null;
|
||||
String longitude = null;
|
||||
|
||||
for (int i = 0; i < attributes.getLength(); i++) {
|
||||
if (attributes.getLocalName(i).equals(ATT_LAT)) {
|
||||
latitude = attributes.getValue(i);
|
||||
} else if (attributes.getLocalName(i).equals(ATT_LON)) {
|
||||
longitude = attributes.getValue(i);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < attributes.getLength(); i++) {
|
||||
if (attributes.getLocalName(i).equals(ATT_LAT)) {
|
||||
latitude = attributes.getValue(i);
|
||||
} else if (attributes.getLocalName(i).equals(ATT_LON)) {
|
||||
longitude = attributes.getValue(i);
|
||||
}
|
||||
}
|
||||
|
||||
// create new location and set attributes
|
||||
Location loc = new Location(LocationManager.GPS_PROVIDER);
|
||||
loc.setLatitude(Double.parseDouble(latitude));
|
||||
loc.setLongitude(Double.parseDouble(longitude));
|
||||
return loc;
|
||||
}
|
||||
// create new location and set attributes
|
||||
Location loc = new Location(LocationManager.GPS_PROVIDER);
|
||||
loc.setLatitude(Double.parseDouble(latitude));
|
||||
loc.setLongitude(Double.parseDouble(longitude));
|
||||
return loc;
|
||||
}
|
||||
|
||||
private void onDescriptionElementEnd() {
|
||||
track.setDescription(content.toString().trim());
|
||||
}
|
||||
private void onDescriptionElementEnd() {
|
||||
track.setDescription(content.toString().trim());
|
||||
}
|
||||
|
||||
private void onNameElementEnd() {
|
||||
track.setName(content.toString().trim());
|
||||
}
|
||||
private void onNameElementEnd() {
|
||||
track.setName(content.toString().trim());
|
||||
}
|
||||
|
||||
/**
|
||||
* Track point finished, write in database
|
||||
*/
|
||||
private void onTrackPointElementEnd() {
|
||||
/**
|
||||
* Track point finished, write in database
|
||||
*/
|
||||
private void onTrackPointElementEnd() {
|
||||
|
||||
if (MyTracksUtils.isValidLocation(location)) {
|
||||
if (MyTracksUtils.isValidLocation(location)) {
|
||||
|
||||
stats.addLocation(location, location.getTime());
|
||||
stats.addLocation(location, location.getTime());
|
||||
|
||||
// insert in db
|
||||
Uri trackPointIdUri = providerUtils.insertTrackPoint(location, track
|
||||
.getId());
|
||||
// insert in db
|
||||
Uri trackPointIdUri = providerUtils.insertTrackPoint(location, track
|
||||
.getId());
|
||||
|
||||
// set start and stop id for track
|
||||
long trackPointId = Long.parseLong(trackPointIdUri.getLastPathSegment());
|
||||
// set start and stop id for track
|
||||
long trackPointId = Long.parseLong(trackPointIdUri.getLastPathSegment());
|
||||
|
||||
// first track point?
|
||||
if (lastLocation == null) {
|
||||
track.setStartId(trackPointId);
|
||||
}
|
||||
// location has no setId method
|
||||
// updating stop id on track every time...
|
||||
track.setStopId(trackPointId);
|
||||
// first track point?
|
||||
if (lastLocation == null) {
|
||||
track.setStartId(trackPointId);
|
||||
}
|
||||
// location has no setId method
|
||||
// updating stop id on track every time...
|
||||
track.setStopId(trackPointId);
|
||||
|
||||
lastLocation = location;
|
||||
numberOfLocations++;
|
||||
}
|
||||
}
|
||||
lastLocation = location;
|
||||
numberOfLocations++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Track finished - update in database
|
||||
*/
|
||||
private void onTrackElementEnd() {
|
||||
/**
|
||||
* Track finished - update in database
|
||||
*/
|
||||
private void onTrackElementEnd() {
|
||||
|
||||
if (lastLocation != null) {
|
||||
if (lastLocation != null) {
|
||||
|
||||
// Calculate statistics for the imported track and update
|
||||
stats.pauseAt(lastLocation.getTime());
|
||||
track.setStopTime(lastLocation.getTime());
|
||||
track.setNumberOfPoints(numberOfLocations);
|
||||
stats.fillStatisticsForTrack(track);
|
||||
providerUtils.updateTrack(track);
|
||||
tracksWritten.add(new Long(track.getId()));
|
||||
// Calculate statistics for the imported track and update
|
||||
stats.pauseAt(lastLocation.getTime());
|
||||
track.setStopTime(lastLocation.getTime());
|
||||
track.setNumberOfPoints(numberOfLocations);
|
||||
stats.fillStatisticsForTrack(track);
|
||||
providerUtils.updateTrack(track);
|
||||
tracksWritten.add(new Long(track.getId()));
|
||||
|
||||
} else {
|
||||
} else {
|
||||
|
||||
// track contains no track points makes not really
|
||||
// sense to import it as we have no location
|
||||
// information -> roll back
|
||||
rollbackUnfinishedTracks();
|
||||
}
|
||||
isCurrentTrackRollbackable = false;
|
||||
}
|
||||
// track contains no track points makes not really
|
||||
// sense to import it as we have no location
|
||||
// information -> roll back
|
||||
rollbackUnfinishedTracks();
|
||||
}
|
||||
isCurrentTrackRollbackable = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* setting time and doing additional calculations as this is the last value
|
||||
* required. Also sets the start time for track and statistics as there is no
|
||||
* start time in the track root element
|
||||
*/
|
||||
private void onTimeElementEnd() {
|
||||
/**
|
||||
* setting time and doing additional calculations as this is the last value
|
||||
* required. Also sets the start time for track and statistics as there is no
|
||||
* start time in the track root element
|
||||
*/
|
||||
private void onTimeElementEnd() {
|
||||
|
||||
long time = parseTimeForAllFormats(content.toString().trim());
|
||||
long time = parseTimeForAllFormats(content.toString().trim());
|
||||
|
||||
if (location != null) {
|
||||
if (location != null) {
|
||||
|
||||
location.setTime(time);
|
||||
// initialize start time with time of first track point
|
||||
if (stats == null) {
|
||||
stats = new TripStatistics(time);
|
||||
track.setStartTime(time);
|
||||
}
|
||||
location.setTime(time);
|
||||
// initialize start time with time of first track point
|
||||
if (stats == null) {
|
||||
stats = new TripStatistics(time);
|
||||
track.setStartTime(time);
|
||||
}
|
||||
|
||||
// We don't have a speed and bearing in GPX, make
|
||||
// something up from
|
||||
// the last two points:
|
||||
if (lastLocation != null) {
|
||||
final long dt = location.getTime() - lastLocation.getTime();
|
||||
if (dt > 0) {
|
||||
final float speed = location.distanceTo(lastLocation) / (dt / 1000);
|
||||
location.setSpeed(speed);
|
||||
}
|
||||
location.setBearing(lastLocation.bearingTo(location));
|
||||
}
|
||||
}
|
||||
}
|
||||
// We don't have a speed and bearing in GPX, make
|
||||
// something up from
|
||||
// the last two points:
|
||||
if (lastLocation != null) {
|
||||
final long dt = location.getTime() - lastLocation.getTime();
|
||||
if (dt > 0) {
|
||||
final float speed = location.distanceTo(lastLocation) / (dt / 1000);
|
||||
location.setSpeed(speed);
|
||||
}
|
||||
location.setBearing(lastLocation.bearingTo(location));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void onAltitudeElementEnd() {
|
||||
if (location != null) {
|
||||
String altitude = content.toString().trim();
|
||||
// make altitude optional
|
||||
if (altitude != null) {
|
||||
location.setAltitude(Double.parseDouble(altitude));
|
||||
}
|
||||
}
|
||||
private void onAltitudeElementEnd() {
|
||||
if (location != null) {
|
||||
String altitude = content.toString().trim();
|
||||
// make altitude optional
|
||||
if (altitude != null) {
|
||||
location.setAltitude(Double.parseDouble(altitude));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If a exception is thrown during the import callers must execute this method
|
||||
* in the catch clause to avoid inconsistent data
|
||||
*/
|
||||
public void rollbackUnfinishedTracks() {
|
||||
if (isCurrentTrackRollbackable) {
|
||||
providerUtils.deleteTrack(track.getId());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* If a exception is thrown during the import callers must execute this method
|
||||
* in the catch clause to avoid inconsistent data
|
||||
*/
|
||||
public void rollbackUnfinishedTracks() {
|
||||
if (isCurrentTrackRollbackable) {
|
||||
providerUtils.deleteTrack(track.getId());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all track ids of the tracks created by this importer run
|
||||
*
|
||||
* @return array of track ids
|
||||
*/
|
||||
private long[] getImportedTrackIds() {
|
||||
// Convert from java.lang.Long for convenience
|
||||
long[] result = new long[tracksWritten.size()];
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i] = tracksWritten.get(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* Get all track ids of the tracks created by this importer run
|
||||
*
|
||||
* @return array of track ids
|
||||
*/
|
||||
private long[] getImportedTrackIds() {
|
||||
// Convert from java.lang.Long for convenience
|
||||
long[] result = new long[tracksWritten.size()];
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i] = tracksWritten.get(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse time trying different formats used in GPX files
|
||||
*
|
||||
* @param timeContents
|
||||
* string with time infomation
|
||||
* @return time as long
|
||||
*/
|
||||
private long parseTimeForAllFormats(String timeContents) {
|
||||
/**
|
||||
* Parse time trying different formats used in GPX files
|
||||
*
|
||||
* @param timeContents
|
||||
* string with time infomation
|
||||
* @return time as long
|
||||
*/
|
||||
private long parseTimeForAllFormats(String timeContents) {
|
||||
|
||||
long t = -1;
|
||||
long t = -1;
|
||||
|
||||
try {
|
||||
// 1st try with time zone at end a la "+0000"
|
||||
t = DATE_FORMAT1.parse(timeContents).getTime();
|
||||
} catch (ParseException e) {
|
||||
// if that fails, try with a literal "Z" at the end
|
||||
// (this is not
|
||||
// according to xml standard, but some gpx files are
|
||||
// like that):
|
||||
try {
|
||||
t = DATE_FORMAT2.parse(timeContents).getTime();
|
||||
} catch (ParseException ex) {
|
||||
// some gpx timestamps have 3 additional digits
|
||||
// at the end.
|
||||
try {
|
||||
t = DATE_FORMAT3.parse(timeContents).getTime();
|
||||
} catch (ParseException exc) {
|
||||
t = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
try {
|
||||
// 1st try with time zone at end a la "+0000"
|
||||
t = DATE_FORMAT1.parse(timeContents).getTime();
|
||||
} catch (ParseException e) {
|
||||
// if that fails, try with a literal "Z" at the end
|
||||
// (this is not
|
||||
// according to xml standard, but some gpx files are
|
||||
// like that):
|
||||
try {
|
||||
t = DATE_FORMAT2.parse(timeContents).getTime();
|
||||
} catch (ParseException ex) {
|
||||
// some gpx timestamps have 3 additional digits
|
||||
// at the end.
|
||||
try {
|
||||
t = DATE_FORMAT3.parse(timeContents).getTime();
|
||||
} catch (ParseException exc) {
|
||||
t = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,132 +36,131 @@ import com.google.android.apps.mytracks.testing.TestingProviderUtilsFactory;
|
||||
*/
|
||||
public class GpxImporterTest extends AndroidTestCase {
|
||||
|
||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(
|
||||
"yyyy-MM-dd'T'hh:mm:ss'Z'");
|
||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat(
|
||||
"yyyy-MM-dd'T'hh:mm:ss'Z'");
|
||||
|
||||
private static final String TRACK_NAME = "blablub";
|
||||
private static final String TRACK_NAME = "blablub";
|
||||
|
||||
private static final String TRACK_DESC = "s'Laebe isch koi Schlotzer";
|
||||
private static final String TRACK_DESC = "s'Laebe isch koi Schlotzer";
|
||||
|
||||
private static final String TRACK_LAT_1 = "48.768364";
|
||||
private static final String TRACK_LON_1 = "9.177886";
|
||||
private static final String TRACK_ELE_1 = "324.0";
|
||||
private static final String TRACK_TIME_1 = "2010-04-22T18:21:00Z";
|
||||
private static final String TRACK_LAT_1 = "48.768364";
|
||||
private static final String TRACK_LON_1 = "9.177886";
|
||||
private static final String TRACK_ELE_1 = "324.0";
|
||||
private static final String TRACK_TIME_1 = "2010-04-22T18:21:00Z";
|
||||
|
||||
private static final String TRACK_LAT_2 = "48.768374";
|
||||
private static final String TRACK_LON_2 = "9.177816";
|
||||
private static final String TRACK_ELE_2 = "333.0";
|
||||
private static final String TRACK_TIME_2 = "2010-04-22T18:21:50Z";
|
||||
private static final String TRACK_LAT_2 = "48.768374";
|
||||
private static final String TRACK_LON_2 = "9.177816";
|
||||
private static final String TRACK_ELE_2 = "333.0";
|
||||
private static final String TRACK_TIME_2 = "2010-04-22T18:21:50Z";
|
||||
|
||||
// TODO use real files from different sources with more track points
|
||||
private static final String VALID_TEST_GPX = "<gpx><trk><name><![CDATA["
|
||||
+ TRACK_NAME + "]]></name><desc><![CDATA[" + TRACK_DESC
|
||||
+ "]]></desc><trkseg>" + "<trkpt lat=\"" + TRACK_LAT_1 + "\" lon=\""
|
||||
+ TRACK_LON_1 + "\"><ele>" + TRACK_ELE_1 + "</ele><time>" + TRACK_TIME_1
|
||||
+ "</time></trkpt> +" + "<trkpt lat=\"" + TRACK_LAT_2 + "\" lon=\""
|
||||
+ TRACK_LON_2 + "\"><ele>" + TRACK_ELE_2 + "</ele><time>" + TRACK_TIME_2
|
||||
+ "</time></trkpt>" + "</trkseg></trk></gpx>";
|
||||
// TODO use real files from different sources with more track points
|
||||
private static final String VALID_TEST_GPX = "<gpx><trk><name><![CDATA["
|
||||
+ TRACK_NAME + "]]></name><desc><![CDATA[" + TRACK_DESC
|
||||
+ "]]></desc><trkseg>" + "<trkpt lat=\"" + TRACK_LAT_1 + "\" lon=\""
|
||||
+ TRACK_LON_1 + "\"><ele>" + TRACK_ELE_1 + "</ele><time>" + TRACK_TIME_1
|
||||
+ "</time></trkpt> +" + "<trkpt lat=\"" + TRACK_LAT_2 + "\" lon=\""
|
||||
+ TRACK_LON_2 + "\"><ele>" + TRACK_ELE_2 + "</ele><time>" + TRACK_TIME_2
|
||||
+ "</time></trkpt>" + "</trkseg></trk></gpx>";
|
||||
|
||||
// invalid xml
|
||||
private static final String INVALID_TEST_GPX = VALID_TEST_GPX.substring(0,
|
||||
VALID_TEST_GPX.length() - 50);
|
||||
// invalid xml
|
||||
private static final String INVALID_TEST_GPX = VALID_TEST_GPX.substring(0,
|
||||
VALID_TEST_GPX.length() - 50);
|
||||
|
||||
private static final long TRACK_ID = 1;
|
||||
private static final long TRACK_POINT_ID = 1;
|
||||
private static final long TRACK_ID = 1;
|
||||
private static final long TRACK_POINT_ID = 1;
|
||||
|
||||
private static final Uri TRACK_ID_URI = ContentUris.appendId(
|
||||
TracksColumns.CONTENT_URI.buildUpon(), TRACK_ID).build();
|
||||
private static final Uri TRACK_POINT_ID_URI = ContentUris.appendId(
|
||||
TrackPointsColumns.CONTENT_URI.buildUpon(), TRACK_POINT_ID).build();
|
||||
private static final Uri TRACK_ID_URI = ContentUris.appendId(
|
||||
TracksColumns.CONTENT_URI.buildUpon(), TRACK_ID).build();
|
||||
private static final Uri TRACK_POINT_ID_URI = ContentUris.appendId(
|
||||
TrackPointsColumns.CONTENT_URI.buildUpon(), TRACK_POINT_ID).build();
|
||||
|
||||
private MyTracksProviderUtils providerUtils;
|
||||
private MyTracksProviderUtils providerUtils;
|
||||
|
||||
private Factory oldProviderUtilsFactory;
|
||||
private Factory oldProviderUtilsFactory;
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
providerUtils = EasyMock.createMock(MyTracksProviderUtils.class);
|
||||
oldProviderUtilsFactory = TestingProviderUtilsFactory
|
||||
.installWithInstance(providerUtils);
|
||||
}
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
providerUtils = EasyMock.createMock(MyTracksProviderUtils.class);
|
||||
oldProviderUtilsFactory = TestingProviderUtilsFactory
|
||||
.installWithInstance(providerUtils);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
TestingProviderUtilsFactory.restoreOldFactory(oldProviderUtilsFactory);
|
||||
super.tearDown();
|
||||
}
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
TestingProviderUtilsFactory.restoreOldFactory(oldProviderUtilsFactory);
|
||||
super.tearDown();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test import success
|
||||
*/
|
||||
public void testImportSuccess() throws Exception {
|
||||
/**
|
||||
* Test import success
|
||||
*/
|
||||
public void testImportSuccess() throws Exception {
|
||||
|
||||
Capture<Track> trackParam = new Capture<Track>();
|
||||
Capture<Location> locParam = new Capture<Location>();
|
||||
Capture<Long> idParam = new Capture<Long>();
|
||||
Capture<Track> trackParam = new Capture<Track>();
|
||||
Capture<Location> locParam = new Capture<Location>();
|
||||
Capture<Long> idParam = new Capture<Long>();
|
||||
|
||||
expect(providerUtils.insertTrack(capture(trackParam))).andReturn(
|
||||
TRACK_ID_URI);
|
||||
expect(providerUtils.insertTrack(capture(trackParam)))
|
||||
.andReturn(TRACK_ID_URI);
|
||||
|
||||
expect(providerUtils.insertTrackPoint(capture(locParam), capture(idParam)))
|
||||
.andReturn(TRACK_POINT_ID_URI);
|
||||
expectLastCall().times(2);
|
||||
expect(providerUtils.insertTrackPoint(capture(locParam), capture(idParam)))
|
||||
.andReturn(TRACK_POINT_ID_URI);
|
||||
expectLastCall().times(2);
|
||||
|
||||
providerUtils.updateTrack(capture(trackParam));
|
||||
providerUtils.updateTrack(capture(trackParam));
|
||||
|
||||
replay(providerUtils);
|
||||
replay(providerUtils);
|
||||
|
||||
InputStream is = new ByteArrayInputStream(VALID_TEST_GPX.getBytes());
|
||||
GpxSaxImporter.importGPXFile(is, providerUtils);
|
||||
InputStream is = new ByteArrayInputStream(VALID_TEST_GPX.getBytes());
|
||||
GpxSaxImporter.importGPXFile(is, providerUtils);
|
||||
|
||||
verify();
|
||||
verify();
|
||||
|
||||
// verify track parameter
|
||||
Track track = trackParam.getValue();
|
||||
assertEquals(TRACK_NAME, track.getName());
|
||||
assertEquals(TRACK_DESC, track.getDescription());
|
||||
assertEquals(DATE_FORMAT.parse(TRACK_TIME_1).getTime(), track
|
||||
.getStartTime());
|
||||
assertNotSame(-1, track.getStartId());
|
||||
assertNotSame(-1, track.getStopId());
|
||||
// verify track parameter
|
||||
Track track = trackParam.getValue();
|
||||
assertEquals(TRACK_NAME, track.getName());
|
||||
assertEquals(TRACK_DESC, track.getDescription());
|
||||
assertEquals(DATE_FORMAT.parse(TRACK_TIME_1).getTime(), track.getStartTime());
|
||||
assertNotSame(-1, track.getStartId());
|
||||
assertNotSame(-1, track.getStopId());
|
||||
|
||||
// verify last location parameter
|
||||
Location loc = locParam.getValue();
|
||||
assertEquals(Double.parseDouble(TRACK_LAT_2), loc.getLatitude());
|
||||
assertEquals(Double.parseDouble(TRACK_LON_2), loc.getLongitude());
|
||||
assertEquals(Double.parseDouble(TRACK_ELE_2), loc.getAltitude());
|
||||
assertEquals(DATE_FORMAT.parse(TRACK_TIME_2).getTime(), loc.getTime());
|
||||
// verify last location parameter
|
||||
Location loc = locParam.getValue();
|
||||
assertEquals(Double.parseDouble(TRACK_LAT_2), loc.getLatitude());
|
||||
assertEquals(Double.parseDouble(TRACK_LON_2), loc.getLongitude());
|
||||
assertEquals(Double.parseDouble(TRACK_ELE_2), loc.getAltitude());
|
||||
assertEquals(DATE_FORMAT.parse(TRACK_TIME_2).getTime(), loc.getTime());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if created track will be deleted on parsing errors
|
||||
*/
|
||||
public void testImportFailure() throws ParserConfigurationException,
|
||||
SAXException, IOException {
|
||||
/**
|
||||
* Test if created track will be deleted on parsing errors
|
||||
*/
|
||||
public void testImportFailure() throws ParserConfigurationException,
|
||||
SAXException, IOException {
|
||||
|
||||
expect(providerUtils.insertTrack((Track) EasyMock.anyObject())).andReturn(
|
||||
TRACK_ID_URI);
|
||||
expect(
|
||||
providerUtils.insertTrackPoint((Location) EasyMock.anyObject(),
|
||||
EasyMock.anyLong())).andReturn(TRACK_POINT_ID_URI);
|
||||
expect(
|
||||
providerUtils.insertTrack((Track) EasyMock.anyObject())).andReturn(TRACK_ID_URI);
|
||||
expect(
|
||||
providerUtils.insertTrackPoint((Location) EasyMock.anyObject(),
|
||||
EasyMock.anyLong())).andReturn(TRACK_POINT_ID_URI);
|
||||
|
||||
expectLastCall().anyTimes();
|
||||
providerUtils.deleteTrack(TRACK_ID);
|
||||
expectLastCall().anyTimes();
|
||||
providerUtils.deleteTrack(TRACK_ID);
|
||||
|
||||
replay(providerUtils);
|
||||
replay(providerUtils);
|
||||
|
||||
InputStream is = new ByteArrayInputStream(INVALID_TEST_GPX.getBytes());
|
||||
InputStream is = new ByteArrayInputStream(INVALID_TEST_GPX.getBytes());
|
||||
|
||||
try {
|
||||
GpxSaxImporter.importGPXFile(is, providerUtils);
|
||||
} catch (SAXException e) {
|
||||
// expected exception
|
||||
}
|
||||
try {
|
||||
GpxSaxImporter.importGPXFile(is, providerUtils);
|
||||
} catch (SAXException e) {
|
||||
// expected exception
|
||||
}
|
||||
|
||||
verify();
|
||||
verify();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user