From 3c5998653ac7237da6f15f68e822aee2c5422521 Mon Sep 17 00:00:00 2001 From: Chuck Greb Date: Wed, 5 Nov 2014 14:27:50 -0500 Subject: [PATCH 1/2] Don't upload traces with range less than 50 meters --- .../mapzen/open/core/DataUploadService.java | 50 ++++++++++++++++++- .../open/core/DataUploadServiceTest.java | 42 ++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/mapzen/open/core/DataUploadService.java b/src/main/java/com/mapzen/open/core/DataUploadService.java index ddf355f6..ac007c2f 100644 --- a/src/main/java/com/mapzen/open/core/DataUploadService.java +++ b/src/main/java/com/mapzen/open/core/DataUploadService.java @@ -24,6 +24,7 @@ import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabaseLockedException; +import android.location.Location; import android.os.AsyncTask; import android.os.IBinder; @@ -68,6 +69,18 @@ public class DataUploadService extends Service { private static final int MIN_NUM_TRACKING_POINTS = 10; + private static final int MIN_RANGE_IN_METERS = 50; + + private static final String RANGE_QUERY_EXT = " from " + + TABLE_ROUTE_GROUP + " inner join " + TABLE_LOCATIONS + " on " + + TABLE_LOCATIONS + "." + COLUMN_ROUTE_ID + " = " + TABLE_ROUTE_GROUP + "." + + COLUMN_ROUTE_ID + " where " + COLUMN_GROUP_ID + " = ?"; + + private static final String MIN_LAT_QUERY = "select min(" + COLUMN_LAT + ")" + RANGE_QUERY_EXT; + private static final String MAX_LAT_QUERY = "select max(" + COLUMN_LAT + ")" + RANGE_QUERY_EXT; + private static final String MIN_LNG_QUERY = "select min(" + COLUMN_LNG + ")" + RANGE_QUERY_EXT; + private static final String MAX_LNG_QUERY = "select max(" + COLUMN_LNG + ")" + RANGE_QUERY_EXT; + private MapzenApplication app; @Inject OAuthRequestFactory requestFactory; @@ -172,7 +185,7 @@ public DOMSource getDocument(String groupId) { DOMSource domSource = null; try { DateTimeFormatter isoDateParser = ISODateTimeFormat.dateTimeNoMillis(); - String selectStatement = String.format(Locale.getDefault(), + String selectStatement = String.format(Locale.US, "SELECT %s, %s, %s, %s, %s ", COLUMN_LAT, COLUMN_LNG, COLUMN_ALT, COLUMN_TIME, COLUMN_SPEED); String fullQuery = selectStatement @@ -208,6 +221,9 @@ public DOMSource getDocument(String groupId) { if (numberOfPoints < MIN_NUM_TRACKING_POINTS) { return null; } + if (calculateMaxRange(groupId) < MIN_RANGE_IN_METERS) { + return null; + } domSource = new DOMSource(documentElement); } catch (ParserConfigurationException e) { Logger.e("Building xml failed: " + e.getMessage()); @@ -215,6 +231,38 @@ public DOMSource getDocument(String groupId) { return domSource; } + /** + * Calculates distance between the two theoretical farthest points in the route. + * + * @return theoretical max range in meters. + */ + private float calculateMaxRange(String groupId) { + final Cursor minLatCursor = app.getDb().rawQuery(MIN_LAT_QUERY, new String[] { groupId }); + final Cursor maxLatCursor = app.getDb().rawQuery(MAX_LAT_QUERY, new String[] { groupId }); + final Cursor minLngCursor = app.getDb().rawQuery(MIN_LNG_QUERY, new String[] { groupId }); + final Cursor maxLngCursor = app.getDb().rawQuery(MAX_LNG_QUERY, new String[] { groupId }); + + minLatCursor.moveToFirst(); + minLngCursor.moveToFirst(); + maxLatCursor.moveToFirst(); + maxLngCursor.moveToFirst(); + + final double minLat = minLatCursor.getDouble(0); + final double maxLat = maxLatCursor.getDouble(0); + final double minLng = minLngCursor.getDouble(0); + final double maxLng = maxLngCursor.getDouble(0); + + final Location min = new Location("temp"); + min.setLatitude(minLat); + min.setLongitude(minLng); + + final Location max = new Location("temp"); + max.setLatitude(maxLat); + max.setLongitude(maxLng); + + return min.distanceTo(max); + } + private void setOutputFormat(Transformer transformer) { Properties outFormat = new Properties(); outFormat.setProperty(INDENT, "yes"); diff --git a/src/test/java/com/mapzen/open/core/DataUploadServiceTest.java b/src/test/java/com/mapzen/open/core/DataUploadServiceTest.java index de986558..313b6da8 100644 --- a/src/test/java/com/mapzen/open/core/DataUploadServiceTest.java +++ b/src/test/java/com/mapzen/open/core/DataUploadServiceTest.java @@ -240,6 +240,18 @@ public void shouldNotCrashWhenDatabaseIsNull() throws Exception { service.onStartCommand(null, 0, 0); } + @Test + public void shouldNotUploadWhenLessThan50MetersTraveled() throws Exception { + Token token = new Token("stuff", "fun"); + app.setAccessToken(token); + String groupId = "test-group-id"; + String routeId = "test-route-id"; + fillLocationsTableAllSamePoint(groupId, routeId, 10); + DataUploadService spy = spy(service); + spy.onStartCommand(null, 0, 0); + verify(spy, never()).submitTrace(anyString(), anyString(), any(byte[].class)); + } + private void makeGroupReady(String groupId) throws Exception { ContentValues insertValues = new ContentValues(); insertValues.put(COLUMN_TABLE_ID, groupId); @@ -281,6 +293,36 @@ private void fillLocationsTable(String groupId, String routeId, double numPoints } } + private void fillLocationsTableAllSamePoint(String groupId, String routeId, double numPoints) + throws Exception { + makeGroupReady(groupId); + + ContentValues routeValues = new ContentValues(); + routeValues.put(COLUMN_TABLE_ID, routeId); + routeValues.put(COLUMN_RAW, "does not matter"); + long routeResults = app.getDb().insert(TABLE_ROUTES, null, routeValues); + + ContentValues routeGroupValues = new ContentValues(); + routeGroupValues.put(COLUMN_ROUTE_ID, routeId); + routeGroupValues.put(COLUMN_GROUP_ID, groupId); + long routeGroupResults = app.getDb().insert(TABLE_ROUTE_GROUP, null, routeGroupValues); + + if (routeResults < 0 || routeGroupResults < 0) { + throw new Exception("database insertion failed"); + } + + final double testLat = 40.7484; + final double testLng = -73.9857; + + ContentValues cv; + for (int i = 0; i < numPoints; i++) { + cv = valuesForLocationCorrection(getTestLocation(testLat, testLng), + getTestLocation(testLat, testLng), getTestInstruction(testLat, testLng), + routeId); + app.getDb().insert(TABLE_LOCATIONS, null, cv); + } + } + private void makeRouteUploaded(String routeId) { ContentValues insertValues = new ContentValues(); insertValues.put(COLUMN_TABLE_ID, routeId); From 80378891ea5cc98aa734577ec431469e0b9aba0f Mon Sep 17 00:00:00 2001 From: Chuck Greb Date: Wed, 5 Nov 2014 15:00:36 -0500 Subject: [PATCH 2/2] Prevents NPE in PageResultsFragment --- .../java/com/mapzen/open/search/PagerResultsFragment.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/mapzen/open/search/PagerResultsFragment.java b/src/main/java/com/mapzen/open/search/PagerResultsFragment.java index 61014466..5113b374 100644 --- a/src/main/java/com/mapzen/open/search/PagerResultsFragment.java +++ b/src/main/java/com/mapzen/open/search/PagerResultsFragment.java @@ -229,9 +229,11 @@ public void add(SimpleFeature simpleFeature) { } public void update(SimpleFeature simpleFeature) { - TextView address = (TextView) pager.findViewById(R.id.address); - address.setText(String.format(Locale.getDefault(), "%s, %s", - simpleFeature.getCity(), simpleFeature.getAdmin())); + if (pager != null) { + TextView address = (TextView) pager.findViewById(R.id.address); + address.setText(String.format(Locale.getDefault(), "%s, %s", + simpleFeature.getCity(), simpleFeature.getAdmin())); + } } public void setSearchResults(List features) {