implemented PolygonGeofence and fixed respective unit test

This commit is contained in:
Timo Tomasini 2016-07-07 15:07:19 +02:00
parent 0b992cbd96
commit c84144e1bd
2 changed files with 59 additions and 13 deletions

View file

@ -22,13 +22,51 @@ public class PolygonGeofence implements Geofence {
*/ */
@Override @Override
public boolean containsLocation(Location location) { public boolean containsLocation(Location location) {
int numberOfCorners = polygonPoints.size(); return pointIsInRegion(location);
}
//adding the first corner at the end so that we can count the edge between last and first corners too private boolean pointIsInRegion(Location aTestLocation) {
List<Location> corners = new ArrayList<Location>(polygonPoints); boolean inside = false;
corners.add(polygonPoints.get(0));
int count = polygonPoints.size();
for (int i = 0; i < count; i++) {
Location beginOfLineLocation = polygonPoints.get(i);
Location endOfLineLocation = polygonPoints.get((i + 1) % count);
if (rayCrossesSegment(aTestLocation, beginOfLineLocation, endOfLineLocation)) {
inside = !inside;
}
}
return inside;
}
private boolean rayCrossesSegment(Location point, Location beginOfLine, Location endOfLine) {
double pointX = point.getLongitude();
double pointY = point.getLatitude();
double beginOfLineX = beginOfLine.getLongitude();
double beginOfLineY = beginOfLine.getLatitude();
double endOfLineX = endOfLine.getLongitude();
double endOfLineY = endOfLine.getLatitude();
if (beginOfLineY > endOfLineY) {
return rayCrossesSegment(point, endOfLine, beginOfLine);
}
if (pointY == beginOfLineY || pointY == endOfLineY) {
pointY += 0.00000001;
}
if ( (pointY > endOfLineY || pointY < beginOfLineY) || (pointX > Math.max(beginOfLineX, endOfLineX)) ) {
return false; return false;
} }
if (pointX < Math.min(beginOfLineX, endOfLineX)) {
return true;
}
double red = (pointY - beginOfLineY) / (double) (pointX - beginOfLineX);
double blue = (endOfLineY - beginOfLineY) / (double) (endOfLineX - beginOfLineX);
return (blue >= red);
}
} }

View file

@ -19,23 +19,31 @@ import static com.esrlabs.geofence.Utils.location;
@Config(constants = BuildConfig.class, emulateSdk = 17) @Config(constants = BuildConfig.class, emulateSdk = 17)
public class PolygonGeofenceTest extends TestCase { public class PolygonGeofenceTest extends TestCase {
// Test polygon defined physically like: // Test polygon defined physically like:
// 48.119033, 11.601664 48.119051, 11.601766 // 48.119033, 11.601664 48.119051, 11.603766
//
// 48.118051, 11.600766 -> This doesn't work - the test was defect
//
// 48.117726, 11.602404 48.117758, 11.602543 // 48.117726, 11.602404 48.117758, 11.602543
public static final Location testPolygonTopRightCorner = location(NETWORK_PROVIDER, 48.119033, 11.601664); public static final Location testPolygonTopLeftCorner = location(NETWORK_PROVIDER, 48.119033, 11.601664);
public static final Location testPolygonTopLeftCorner = location(NETWORK_PROVIDER, 48.119051, 11.601966); public static final Location testPolygonTopRightCorner = location(NETWORK_PROVIDER, 48.119051, 11.603766);
public static final Location testPolygonBottomRightCorner = location(NETWORK_PROVIDER, 48.116726, 11.602404); public static final Location testPolygonBottomRightCorner = location(NETWORK_PROVIDER, 48.117758, 11.602543);
public static final Location testPolygonBottomLeftCorner = location(NETWORK_PROVIDER, 48.116758, 11.602743); public static final Location testPolygonBottomLeftCorner = location(NETWORK_PROVIDER, 48.117726, 11.602404);
public static final PolygonGeofence testGeofence = new PolygonGeofence(testPolygonTopRightCorner, testPolygonTopLeftCorner, public static final PolygonGeofence testGeofence = new PolygonGeofence(testPolygonTopRightCorner, testPolygonTopLeftCorner,
testPolygonBottomRightCorner, testPolygonBottomLeftCorner); testPolygonBottomRightCorner, testPolygonBottomLeftCorner);
@Test @Test
public void testContainsLocation() throws Exception { public void testContainsLocation() throws Exception {
assertTrue(testGeofence.containsLocation(someLocationInside())); assertTrue(testGeofence.containsLocation(someLocationInside()));
assertTrue(testGeofence.containsLocation(anotherLocationInside()));
assertFalse(testGeofence.containsLocation(someLocationOutside())); assertFalse(testGeofence.containsLocation(someLocationOutside()));
} }
private Location someLocationInside() { private Location someLocationInside() {
return location(NETWORK_PROVIDER, testPolygonTopRightCorner.getLatitude() - 0.001, testPolygonTopRightCorner.getLongitude() - 0.001); return location(NETWORK_PROVIDER, testPolygonTopRightCorner.getLatitude() - 0.0001, testPolygonTopRightCorner.getLongitude() - 0.0001);
}
private Location anotherLocationInside() {
return location(NETWORK_PROVIDER, 48.118, 11.60245);
} }
private Location someLocationOutside() { private Location someLocationOutside() {