implemented PolygonGeofence and fixed respective unit test
This commit is contained in:
parent
0b992cbd96
commit
c84144e1bd
2 changed files with 59 additions and 13 deletions
|
@ -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
|
|
||||||
List<Location> corners = new ArrayList<Location>(polygonPoints);
|
|
||||||
corners.add(polygonPoints.get(0));
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean pointIsInRegion(Location aTestLocation) {
|
||||||
|
boolean inside = false;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
Loading…
Reference in a new issue