forked from upstream-mirrors/OpenTracks
Merge chart changes.
This commit is contained in:
@@ -60,6 +60,7 @@ import java.util.ArrayList;
|
|||||||
public class ChartActivity extends Activity implements
|
public class ChartActivity extends Activity implements
|
||||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
|
private final static int BUFFER_SIZE = 1024;
|
||||||
private double profileLength = 0;
|
private double profileLength = 0;
|
||||||
|
|
||||||
private boolean metricUnits = true;
|
private boolean metricUnits = true;
|
||||||
@@ -101,7 +102,7 @@ public class ChartActivity extends Activity implements
|
|||||||
/*
|
/*
|
||||||
* UI elements:
|
* UI elements:
|
||||||
*/
|
*/
|
||||||
private ChartView cv;
|
private ChartView chartView;
|
||||||
private MenuItem chartSettingsMenuItem;
|
private MenuItem chartSettingsMenuItem;
|
||||||
private LinearLayout busyPane;
|
private LinearLayout busyPane;
|
||||||
private ZoomControls zoomControls;
|
private ZoomControls zoomControls;
|
||||||
@@ -118,10 +119,10 @@ public class ChartActivity extends Activity implements
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
busyPane.setVisibility(View.GONE);
|
busyPane.setVisibility(View.GONE);
|
||||||
zoomControls.setIsZoomInEnabled(cv.canZoomIn());
|
zoomControls.setIsZoomInEnabled(chartView.canZoomIn());
|
||||||
zoomControls.setIsZoomOutEnabled(cv.canZoomOut());
|
zoomControls.setIsZoomOutEnabled(chartView.canZoomOut());
|
||||||
cv.setShowPointer(selectedTrackIsRecording());
|
chartView.setShowPointer(selectedTrackIsRecording());
|
||||||
cv.invalidate();
|
chartView.invalidate();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -158,54 +159,12 @@ public class ChartActivity extends Activity implements
|
|||||||
private Handler updateTrackHandler;
|
private Handler updateTrackHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A runnable that update the profile from the provider.
|
* A runnable that updates the profile from the provider.
|
||||||
*/
|
*/
|
||||||
private final Runnable updateTrackRunnable = new Runnable() {
|
private final Runnable updateTrackRunnable = new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
Log.d(MyTracksConstants.TAG, "MyTracks: Updating chart.");
|
readNewTrackPoints();
|
||||||
Track track = providerUtils.getTrack(recordingTrackId);
|
|
||||||
if (track == null) {
|
|
||||||
Log.w(MyTracksConstants.TAG, "MyTracks: track not found");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Cursor cursor = null;
|
|
||||||
try {
|
|
||||||
cursor = providerUtils.getLocationsCursor(recordingTrackId,
|
|
||||||
lastSeenLocationId + 1,
|
|
||||||
MyTracksConstants.MAX_DISPLAYED_TRACK_POINTS - cv.getData().size(),
|
|
||||||
true);
|
|
||||||
if (cursor != null) {
|
|
||||||
if (cursor.moveToLast()) {
|
|
||||||
final int idColumnIdx =
|
|
||||||
cursor.getColumnIndexOrThrow(TrackPointsColumns._ID);
|
|
||||||
ArrayList<double[]> data = new ArrayList<double[]>();
|
|
||||||
// Need two locations so we can keep track of the last location.
|
|
||||||
Location location = new MyTracksLocation("");
|
|
||||||
do {
|
|
||||||
lastSeenLocationId = cursor.getLong(idColumnIdx);
|
|
||||||
providerUtils.fillLocation(cursor, location);
|
|
||||||
if (MyTracksUtils.isValidLocation(location)) {
|
|
||||||
double[] point = new double[6];
|
|
||||||
location = getDataPoint(location, track, point);
|
|
||||||
data.add(point);
|
|
||||||
}
|
|
||||||
} while (cursor.moveToPrevious());
|
|
||||||
cv.addDataPoints(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
Log.w(MyTracksConstants.TAG, "Caught an unexpected exception.", e);
|
|
||||||
} finally {
|
|
||||||
if (cursor != null) {
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
uiHandler.post(new Runnable() {
|
|
||||||
public void run() {
|
|
||||||
cv.invalidate();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -222,13 +181,13 @@ public class ChartActivity extends Activity implements
|
|||||||
metricUnits =
|
metricUnits =
|
||||||
sharedPreferences.getBoolean(getString(R.string.metric_units_key),
|
sharedPreferences.getBoolean(getString(R.string.metric_units_key),
|
||||||
true);
|
true);
|
||||||
cv.setMetricUnits(metricUnits);
|
chartView.setMetricUnits(metricUnits);
|
||||||
readProfileAsync();
|
readProfileAsync();
|
||||||
} else if (key.equals(getString(R.string.report_speed_key))) {
|
} else if (key.equals(getString(R.string.report_speed_key))) {
|
||||||
reportSpeed =
|
reportSpeed =
|
||||||
sharedPreferences.getBoolean(getString(R.string.report_speed_key),
|
sharedPreferences.getBoolean(getString(R.string.report_speed_key),
|
||||||
true);
|
true);
|
||||||
cv.setReportSpeed(reportSpeed, this);
|
chartView.setReportSpeed(reportSpeed, this);
|
||||||
readProfileAsync();
|
readProfileAsync();
|
||||||
} else if (key.equals(getString(R.string.recording_track_key))) {
|
} else if (key.equals(getString(R.string.recording_track_key))) {
|
||||||
recordingTrackId =
|
recordingTrackId =
|
||||||
@@ -254,11 +213,11 @@ public class ChartActivity extends Activity implements
|
|||||||
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||||
setContentView(R.layout.mytracks_charts);
|
setContentView(R.layout.mytracks_charts);
|
||||||
ViewGroup layout = (ViewGroup) findViewById(R.id.elevation_chart);
|
ViewGroup layout = (ViewGroup) findViewById(R.id.elevation_chart);
|
||||||
cv = new ChartView(this);
|
chartView = new ChartView(this);
|
||||||
cv.setMode(this.mode);
|
chartView.setMode(this.mode);
|
||||||
LayoutParams params =
|
LayoutParams params =
|
||||||
new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
|
new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
|
||||||
layout.addView(cv, params);
|
layout.addView(chartView, params);
|
||||||
|
|
||||||
SharedPreferences preferences =
|
SharedPreferences preferences =
|
||||||
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
|
getSharedPreferences(MyTracksSettings.SETTINGS_NAME, 0);
|
||||||
@@ -269,10 +228,10 @@ public class ChartActivity extends Activity implements
|
|||||||
preferences.getLong(getString(R.string.recording_track_key), -1);
|
preferences.getLong(getString(R.string.recording_track_key), -1);
|
||||||
metricUnits = preferences.getBoolean(getString(R.string.metric_units_key),
|
metricUnits = preferences.getBoolean(getString(R.string.metric_units_key),
|
||||||
true);
|
true);
|
||||||
cv.setMetricUnits(metricUnits);
|
chartView.setMetricUnits(metricUnits);
|
||||||
reportSpeed = preferences.getBoolean(getString(R.string.report_speed_key),
|
reportSpeed = preferences.getBoolean(getString(R.string.report_speed_key),
|
||||||
true);
|
true);
|
||||||
cv.setReportSpeed(reportSpeed, this);
|
chartView.setReportSpeed(reportSpeed, this);
|
||||||
preferences.registerOnSharedPreferenceChangeListener(this);
|
preferences.registerOnSharedPreferenceChangeListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,7 +291,7 @@ public class ChartActivity extends Activity implements
|
|||||||
ChartActivity.this.runOnUiThread(new Runnable() {
|
ChartActivity.this.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
cv.invalidate();
|
chartView.invalidate();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -384,21 +343,21 @@ public class ChartActivity extends Activity implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void zoomIn() {
|
private void zoomIn() {
|
||||||
cv.zoomIn();
|
chartView.zoomIn();
|
||||||
zoomControls.setIsZoomInEnabled(cv.canZoomIn());
|
zoomControls.setIsZoomInEnabled(chartView.canZoomIn());
|
||||||
zoomControls.setIsZoomOutEnabled(cv.canZoomOut());
|
zoomControls.setIsZoomOutEnabled(chartView.canZoomOut());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void zoomOut() {
|
private void zoomOut() {
|
||||||
cv.zoomOut();
|
chartView.zoomOut();
|
||||||
zoomControls.setIsZoomInEnabled(cv.canZoomIn());
|
zoomControls.setIsZoomInEnabled(chartView.canZoomIn());
|
||||||
zoomControls.setIsZoomOutEnabled(cv.canZoomOut());
|
zoomControls.setIsZoomOutEnabled(chartView.canZoomOut());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMode(Mode newMode) {
|
public void setMode(Mode newMode) {
|
||||||
if (this.mode != newMode) {
|
if (this.mode != newMode) {
|
||||||
this.mode = newMode;
|
this.mode = newMode;
|
||||||
cv.setMode(this.mode);
|
chartView.setMode(this.mode);
|
||||||
readProfileAsync();
|
readProfileAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -408,12 +367,12 @@ public class ChartActivity extends Activity implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setSeriesEnabled(int index, boolean enabled) {
|
public void setSeriesEnabled(int index, boolean enabled) {
|
||||||
cv.getChartValueSeries(index).setEnabled(enabled);
|
chartView.getChartValueSeries(index).setEnabled(enabled);
|
||||||
runOnUiThread(updateChart);
|
runOnUiThread(updateChart);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSeriesEnabled(int index) {
|
public boolean isSeriesEnabled(int index) {
|
||||||
return cv.getChartValueSeries(index).isEnabled();
|
return chartView.getChartValueSeries(index).isEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readWaypoints() {
|
private void readWaypoints() {
|
||||||
@@ -421,7 +380,7 @@ public class ChartActivity extends Activity implements
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Cursor cursor = null;
|
Cursor cursor = null;
|
||||||
cv.clearWaypoints();
|
chartView.clearWaypoints();
|
||||||
try {
|
try {
|
||||||
// We will silently drop extra waypoints to make the app responsive.
|
// We will silently drop extra waypoints to make the app responsive.
|
||||||
cursor =
|
cursor =
|
||||||
@@ -431,7 +390,7 @@ public class ChartActivity extends Activity implements
|
|||||||
if (cursor.moveToFirst()) {
|
if (cursor.moveToFirst()) {
|
||||||
do {
|
do {
|
||||||
Waypoint wpt = providerUtils.createWaypoint(cursor);
|
Waypoint wpt = providerUtils.createWaypoint(cursor);
|
||||||
cv.addWaypoint(wpt);
|
chartView.addWaypoint(wpt);
|
||||||
} while (cursor.moveToNext());
|
} while (cursor.moveToNext());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -575,7 +534,7 @@ public class ChartActivity extends Activity implements
|
|||||||
* Sets the chart data points reading from the provider. This is non-blocking.
|
* Sets the chart data points reading from the provider. This is non-blocking.
|
||||||
*/
|
*/
|
||||||
private void readProfileAsync() {
|
private void readProfileAsync() {
|
||||||
cv.reset();
|
chartView.reset();
|
||||||
updateTrackHandler.post(new Runnable() {
|
updateTrackHandler.post(new Runnable() {
|
||||||
public void run() {
|
public void run() {
|
||||||
runOnUiThread(showSpinner);
|
runOnUiThread(showSpinner);
|
||||||
@@ -594,7 +553,6 @@ public class ChartActivity extends Activity implements
|
|||||||
profileLength = 0;
|
profileLength = 0;
|
||||||
lastLocation = null;
|
lastLocation = null;
|
||||||
startTime = -1;
|
startTime = -1;
|
||||||
Cursor cursor = null;
|
|
||||||
if (selectedTrackId < 0) {
|
if (selectedTrackId < 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -602,26 +560,70 @@ public class ChartActivity extends Activity implements
|
|||||||
if (track == null) {
|
if (track == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
long lastLocationRead = track.getStartId();
|
lastSeenLocationId = track.getStartId();
|
||||||
long totalLocations = track.getStopId() - track.getStartId();
|
final ArrayList<double[]> theData = readPointsToList(track);
|
||||||
|
runOnUiThread(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
chartView.setDataPoints(theData);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Limit the number of chart readings. Ideally we would want around 1024.
|
/**
|
||||||
int chartSamplingFrequency = Math.max(1, (int) (totalLocations / 1024.0));
|
* Read all new track points.
|
||||||
int bufferSize = 1024;
|
*/
|
||||||
|
private void readNewTrackPoints() {
|
||||||
|
Log.i(MyTracksConstants.TAG, "MyTracks: Updating chart last seen: " + lastSeenLocationId);
|
||||||
|
Track track = providerUtils.getTrack(recordingTrackId);
|
||||||
|
if (track == null) {
|
||||||
|
Log.w(MyTracksConstants.TAG, "MyTracks: track not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
chartView.addDataPoints(readPointsToList(track));
|
||||||
|
uiHandler.post(new Runnable() {
|
||||||
|
public void run() {
|
||||||
|
chartView.invalidate();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Log.i(MyTracksConstants.TAG, "MyTracks: Updated chart last seen: " + lastSeenLocationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the frequency at which points should be displayed.
|
||||||
|
* Limit the number of chart readings. Ideally we would want around 1024.
|
||||||
|
* @param track The track which will be displayed.
|
||||||
|
* @return The inverse of the frequency of points to be displayed.
|
||||||
|
*/
|
||||||
|
private int getSamplingFrequency(Track track) {
|
||||||
|
long totalLocations = track.getStopId() - track.getStartId();
|
||||||
|
return Math.max(1, (int) (totalLocations / 1024.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Cursor getLocationsCursor(long lastLocationRead) {
|
||||||
|
return providerUtils.getLocationsCursor(selectedTrackId, lastLocationRead, BUFFER_SIZE, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read all of the points to a list.
|
||||||
|
* @param track The track which will be displayed.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private ArrayList<double[]> readPointsToList(Track track) {
|
||||||
|
Cursor cursor = null;
|
||||||
|
long lastLocationRead = lastSeenLocationId;
|
||||||
|
int points = 0;
|
||||||
|
int chartSamplingFrequency = getSamplingFrequency(track);
|
||||||
|
ArrayList<double[]> result = new ArrayList<double[]>();
|
||||||
|
// Need two locations so we can keep track of the last location.
|
||||||
|
Location location = new MyTracksLocation("");
|
||||||
try {
|
try {
|
||||||
final ArrayList<double[]> theData = new ArrayList<double[]>();
|
while (lastSeenLocationId < track.getStopId()) {
|
||||||
int points = 0;
|
cursor = getLocationsCursor(lastLocationRead);
|
||||||
// Need two locations so we can keep track of the last location.
|
|
||||||
Location location = new MyTracksLocation("");
|
|
||||||
while (lastLocationRead < track.getStopId()) {
|
|
||||||
cursor = providerUtils.getLocationsCursor(
|
|
||||||
selectedTrackId, lastLocationRead, bufferSize, false);
|
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
elevationBuffer.reset();
|
elevationBuffer.reset();
|
||||||
speedBuffer.reset();
|
speedBuffer.reset();
|
||||||
if (cursor.moveToFirst()) {
|
if (cursor.moveToFirst()) {
|
||||||
final int idColumnIdx =
|
final int idColumnIdx = cursor.getColumnIndexOrThrow(TrackPointsColumns._ID);
|
||||||
cursor.getColumnIndexOrThrow(TrackPointsColumns._ID);
|
|
||||||
while (cursor.moveToNext()) {
|
while (cursor.moveToNext()) {
|
||||||
points++;
|
points++;
|
||||||
providerUtils.fillLocation(cursor, location);
|
providerUtils.fillLocation(cursor, location);
|
||||||
@@ -632,26 +634,20 @@ public class ChartActivity extends Activity implements
|
|||||||
double[] point = new double[6];
|
double[] point = new double[6];
|
||||||
location = getDataPoint(location, track, point);
|
location = getDataPoint(location, track, point);
|
||||||
if (points % chartSamplingFrequency == 0) {
|
if (points % chartSamplingFrequency == 0) {
|
||||||
theData.add(point);
|
result.add(point);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
lastLocationRead += bufferSize;
|
lastLocationRead += BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
lastLocationRead += bufferSize;
|
lastLocationRead += BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
cursor.close();
|
cursor.close();
|
||||||
cursor = null;
|
cursor = null;
|
||||||
}
|
}
|
||||||
runOnUiThread(new Runnable() {
|
return result;
|
||||||
public void run() {
|
|
||||||
cv.setDataPoints(theData);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
Log.w(MyTracksConstants.TAG, "Caught unexpected exception.", e);
|
|
||||||
} finally {
|
} finally {
|
||||||
if (cursor != null) {
|
if (cursor != null) {
|
||||||
cursor.close();
|
cursor.close();
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ public class ChartView extends View {
|
|||||||
R.color.speed_fill,
|
R.color.speed_fill,
|
||||||
R.color.speed_border,
|
R.color.speed_border,
|
||||||
new ZoomSettings(MAX_INTERVALS, 0, Integer.MIN_VALUE,
|
new ZoomSettings(MAX_INTERVALS, 0, Integer.MIN_VALUE,
|
||||||
new int[] {5, 10, 20, 50}),
|
new int[] {1, 5, 10, 20, 50}),
|
||||||
R.string.speed);
|
R.string.speed);
|
||||||
series[POWER_SERIES] =
|
series[POWER_SERIES] =
|
||||||
new ChartValueSeries(context,
|
new ChartValueSeries(context,
|
||||||
@@ -610,7 +610,8 @@ public class ChartView extends View {
|
|||||||
|
|
||||||
c.translate(getScrollX(), 0);
|
c.translate(getScrollX(), 0);
|
||||||
drawYAxis(c);
|
drawYAxis(c);
|
||||||
final int spacer = 5;
|
float density = getContext().getResources().getDisplayMetrics().density;
|
||||||
|
final int spacer = (int) (5 * density);
|
||||||
int x = leftBorder - spacer;
|
int x = leftBorder - spacer;
|
||||||
for (ChartValueSeries cvs : series) {
|
for (ChartValueSeries cvs : series) {
|
||||||
if (cvs.isEnabled() && cvs.hasData()) {
|
if (cvs.isEnabled() && cvs.hasData()) {
|
||||||
@@ -726,9 +727,10 @@ public class ChartView extends View {
|
|||||||
maxLength += cvs.getMaxLabelLength();
|
maxLength += cvs.getMaxLabelLength();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
leftBorder = 4 + 8 * maxLength;
|
|
||||||
effectiveWidth = w - leftBorder - RIGHT_BORDER;
|
|
||||||
float density = getContext().getResources().getDisplayMetrics().density;
|
float density = getContext().getResources().getDisplayMetrics().density;
|
||||||
|
// TODO: This should be function of the number of variables displayed.
|
||||||
|
leftBorder = (int) (density * (4 + 8 * maxLength));
|
||||||
|
effectiveWidth = w - leftBorder - RIGHT_BORDER;
|
||||||
bottomBorder = (int) (density * BOTTOM_BORDER);
|
bottomBorder = (int) (density * BOTTOM_BORDER);
|
||||||
topBorder = (int) (density * TOP_BORDER);
|
topBorder = (int) (density * TOP_BORDER);
|
||||||
effectiveHeight = h - topBorder - bottomBorder;
|
effectiveHeight = h - topBorder - bottomBorder;
|
||||||
@@ -739,8 +741,9 @@ public class ChartView extends View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getY(ChartValueSeries cvs, double y) {
|
private int getY(ChartValueSeries cvs, double y) {
|
||||||
|
int effectiveSpread = cvs.getInterval() * MAX_INTERVALS;
|
||||||
return topBorder + effectiveHeight
|
return topBorder + effectiveHeight
|
||||||
- (int) ((y - cvs.getMin()) * effectiveHeight / cvs.getSpread());
|
- (int) ((y - cvs.getMin()) * effectiveHeight / effectiveSpread);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void drawXLabels(Canvas c) {
|
private void drawXLabels(Canvas c) {
|
||||||
|
|||||||
Reference in New Issue
Block a user