add method 'isWithin' for single WP (being called from RoutingContext.cleanNogolist)

This commit is contained in:
ntruchsess 2018-01-22 18:59:10 +01:00
parent 48d60dd69e
commit 32a49bfa32
3 changed files with 46 additions and 15 deletions

View file

@ -160,12 +160,26 @@ public class OsmNogoPolygon extends OsmNodeNamed
} }
/** /**
* intersectsOrIsWithin * tests whether a point is within the polygon.
* * The current implementation doesn't produce consistent results for points
* being located exactly on the edge of the polygon. That doesn't have
* major impact on the routing-results though.
* For this method the winding-number algorithm is being used. That means a
* point being within an overlapping region of the polygon is also taken as
* being 'inside' the polygon.
* @param lon longitude of point
* @param lat latitude of point
* @return true if point is inside of polygon, false otherwise
*/
public boolean isWithin(int lon, int lat)
{
return wn_PnPoly(new Point(lon,lat),points) > 0;
}
/**
* tests whether a segment defined by lon and lat of two points does either * tests whether a segment defined by lon and lat of two points does either
* intersect the polygon or any of the endpoints (or both) are enclosed by * intersect the polygon or any of the endpoints (or both) are enclosed by
* the polygon. Any point being positioned on any of the polygons edges is * the polygon. For this test the winding-number algorithm is
* defined as being 'inside'. For this test the winding-number algorithm is
* being used. That means a point being within an overlapping region of the * being used. That means a point being within an overlapping region of the
* polygon is also taken as being 'inside' the polygon. * polygon is also taken as being 'inside' the polygon.
* *
@ -177,8 +191,8 @@ public class OsmNogoPolygon extends OsmNodeNamed
*/ */
public boolean intersectsOrIsWithin(int lon0, int lat0, int lon1, int lat1) public boolean intersectsOrIsWithin(int lon0, int lat0, int lon1, int lat1)
{ {
Point p0 = new Point (lon0,lat0); final Point p0 = new Point (lon0,lat0);
Point p1 = new Point (lon1,lat1); final Point p1 = new Point (lon1,lat1);
// is start or endpoint within polygon? // is start or endpoint within polygon?
if ((wn_PnPoly(p0, points) > 0) || (wn_PnPoly(p1, points) > 0)) if ((wn_PnPoly(p0, points) > 0) || (wn_PnPoly(p1, points) > 0))
{ {
@ -199,7 +213,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
return false; return false;
} }
/* Copyright 2001 softSurfer, 2012 Dan Sunday, 2018 Norbert Truchses /* Copyright 2001 softSurfer, 2012 Dan Sunday, 2018 Norbert Truchsess
This code may be freely used and modified for any purpose providing that This code may be freely used and modified for any purpose providing that
this copyright notice is included with it. SoftSurfer makes no warranty for this copyright notice is included with it. SoftSurfer makes no warranty for
this code, and cannot be held liable for any real or imagined damage this code, and cannot be held liable for any real or imagined damage
@ -242,7 +256,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
return ((cn & 1) > 0); // 0 if even (out), and 1 if odd (in) return ((cn & 1) > 0); // 0 if even (out), and 1 if odd (in)
} }
/* Copyright 2001 softSurfer, 2012 Dan Sunday, 2018 Norbert Truchses /* Copyright 2001 softSurfer, 2012 Dan Sunday, 2018 Norbert Truchsess
This code may be freely used and modified for any purpose providing that This code may be freely used and modified for any purpose providing that
this copyright notice is included with it. SoftSurfer makes no warranty for this copyright notice is included with it. SoftSurfer makes no warranty for
this code, and cannot be held liable for any real or imagined damage this code, and cannot be held liable for any real or imagined damage
@ -259,8 +273,8 @@ public class OsmNogoPolygon extends OsmNodeNamed
private static int wn_PnPoly(final Point p, final List<Point> v) { private static int wn_PnPoly(final Point p, final List<Point> v) {
int wn = 0; // the winding number counter int wn = 0; // the winding number counter
final int px = p.x; final long px = p.x;
final int py = p.y; final long py = p.y;
// loop through all edges of the polygon // loop through all edges of the polygon
final int i_last = v.size()-1; final int i_last = v.size()-1;
@ -283,7 +297,9 @@ public class OsmNogoPolygon extends OsmNodeNamed
++wn; // have a valid up intersect ++wn; // have a valid up intersect
} }
} }
} else { // start y > p.y (no test needed) }
else // start y > p.y (no test needed)
{
if (p1y <= py) // a downward crossing if (p1y <= py) // a downward crossing
{ // p right of edge { // p right of edge
if (((p1x - p0x) * (py - p0y) - (px - p0x) * (p1y - p0y)) < 0) if (((p1x - p0x) * (py - p0y) - (px - p0x) * (p1y - p0y)) < 0)
@ -298,7 +314,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
return wn; return wn;
} }
/* Copyright 2001 softSurfer, 2012 Dan Sunday, 2018 Norbert Truchses /* Copyright 2001 softSurfer, 2012 Dan Sunday, 2018 Norbert Truchsess
This code may be freely used and modified for any purpose providing that This code may be freely used and modified for any purpose providing that
this copyright notice is included with it. SoftSurfer makes no warranty for this copyright notice is included with it. SoftSurfer makes no warranty for
this code, and cannot be held liable for any real or imagined damage this code, and cannot be held liable for any real or imagined damage
@ -348,7 +364,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
return false; return false;
} }
/* Copyright 2001 softSurfer, 2012 Dan Sunday, 2018 Norbert Truchses /* Copyright 2001 softSurfer, 2012 Dan Sunday, 2018 Norbert Truchsess
This code may be freely used and modified for any purpose providing that This code may be freely used and modified for any purpose providing that
this copyright notice is included with it. SoftSurfer makes no warranty for this copyright notice is included with it. SoftSurfer makes no warranty for
this code, and cannot be held liable for any real or imagined damage this code, and cannot be held liable for any real or imagined damage

View file

@ -215,7 +215,9 @@ public final class RoutingContext
boolean goodGuy = true; boolean goodGuy = true;
for( OsmNodeNamed wp : waypoints ) for( OsmNodeNamed wp : waypoints )
{ {
if ( wp.calcDistance( nogo ) < radiusInMeter ) if ( wp.calcDistance( nogo ) < radiusInMeter
&& (!(nogo instanceof OsmNogoPolygon)
|| ((OsmNogoPolygon)nogo).isWithin(wp.ilon, wp.ilat)))
{ {
goodGuy = false; goodGuy = false;
break; break;

View file

@ -68,6 +68,19 @@ public class OsmNogoPolygonTest {
} }
} }
@Test
public void testIsWithin() {
// for points exactly on the edge of the polygon the result is not the same for all directions.
// that doesn't have a major impact on routing though.
double[] plons = { 0.0, 0.5, 1.0, -1.5, -0.5, }; // 1.0, 1.0, 0.5, 0.5, 0.5,
double[] plats = { 0.0, 1.5, 0.0, 0.5, -1.5, }; // -1.0, -0.1, -0.1, 0.0, 0.1,
boolean[] within = { true, false, false, false, false, }; // false, false, false, false, false,
for (int i=0; i<plons.length; i++) {
assertEquals("("+plons[i]+","+plats[i]+")",within[i],p.isWithin(toOsmLon(plons[i]), toOsmLat(plats[i])));
}
}
@Test @Test
public void testIntersectsOrIsWithin() { public void testIntersectsOrIsWithin() {
double[] p0lons = { 0.0, 1.0, -0.5, 0.5, 0.7, 0.7, 0.7, -1.5, }; double[] p0lons = { 0.0, 1.0, -0.5, 0.5, 0.7, 0.7, 0.7, -1.5, };