Remove some duplicate codes and magic numbers
This commit is contained in:
parent
c78b56645c
commit
5a62480bd3
9 changed files with 128 additions and 120 deletions
|
@ -25,6 +25,8 @@ package btools.router;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import btools.util.CheapRulerSingleton;
|
||||||
|
|
||||||
public class OsmNogoPolygon extends OsmNodeNamed
|
public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
{
|
{
|
||||||
public final static class Point
|
public final static class Point
|
||||||
|
@ -40,9 +42,9 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
}
|
}
|
||||||
|
|
||||||
public final List<Point> points = new ArrayList<Point>();
|
public final List<Point> points = new ArrayList<Point>();
|
||||||
|
|
||||||
public final boolean isClosed;
|
public final boolean isClosed;
|
||||||
|
|
||||||
public OsmNogoPolygon(boolean closed)
|
public OsmNogoPolygon(boolean closed)
|
||||||
{
|
{
|
||||||
this.isClosed = closed;
|
this.isClosed = closed;
|
||||||
|
@ -55,15 +57,6 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
points.add(new Point(lon, lat));
|
points.add(new Point(lon, lat));
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static double coslat(double lat)
|
|
||||||
{
|
|
||||||
final double l = (lat - 90000000) * 0.00000001234134; // 0.01234134 = Pi/(sqrt(2)*180)
|
|
||||||
final double l2 = l*l;
|
|
||||||
final double l4 = l2*l2;
|
|
||||||
// final double l6 = l4*l2;
|
|
||||||
return 1.- l2 + l4 / 6.; // - l6 / 90;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* calcBoundingCircle is inspired by the algorithm described on
|
* calcBoundingCircle is inspired by the algorithm described on
|
||||||
* http://geomalgorithms.com/a08-_containers.html
|
* http://geomalgorithms.com/a08-_containers.html
|
||||||
|
@ -74,7 +67,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
* with each iteration.
|
* with each iteration.
|
||||||
* This is done to ensure the calculated radius being used
|
* This is done to ensure the calculated radius being used
|
||||||
* in RoutingContext.calcDistance will actually contain the whole polygon.
|
* in RoutingContext.calcDistance will actually contain the whole polygon.
|
||||||
*
|
*
|
||||||
* For reasonable distributed vertices the implemented algorithm runs in O(n*ln(n)).
|
* For reasonable distributed vertices the implemented algorithm runs in O(n*ln(n)).
|
||||||
* As this is only run once on initialization of OsmNogoPolygon this methods
|
* As this is only run once on initialization of OsmNogoPolygon this methods
|
||||||
* overall usage of cpu is neglegible in comparism to the cpu-usage of the
|
* overall usage of cpu is neglegible in comparism to the cpu-usage of the
|
||||||
|
@ -82,10 +75,12 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
*/
|
*/
|
||||||
public void calcBoundingCircle()
|
public void calcBoundingCircle()
|
||||||
{
|
{
|
||||||
|
CheapRulerSingleton cr = CheapRulerSingleton.getInstance();
|
||||||
|
|
||||||
int cxmin, cxmax, cymin, cymax;
|
int cxmin, cxmax, cymin, cymax;
|
||||||
cxmin = cymin = Integer.MAX_VALUE;
|
cxmin = cymin = Integer.MAX_VALUE;
|
||||||
cxmax = cymax = Integer.MIN_VALUE;
|
cxmax = cymax = Integer.MIN_VALUE;
|
||||||
|
|
||||||
// first calculate a starting center point as center of boundingbox
|
// first calculate a starting center point as center of boundingbox
|
||||||
for (int i = 0; i < points.size(); i++)
|
for (int i = 0; i < points.size(); i++)
|
||||||
{
|
{
|
||||||
|
@ -110,7 +105,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
|
|
||||||
double cx = (cxmax+cxmin) / 2.0; // center of circle
|
double cx = (cxmax+cxmin) / 2.0; // center of circle
|
||||||
double cy = (cymax+cymin) / 2.0;
|
double cy = (cymax+cymin) / 2.0;
|
||||||
double ccoslat = coslat(cy); // cosin at latitude of center
|
double ccoslat = cr.cosIlat((int) cy); // cosin at latitude of center
|
||||||
double rad = 0; // radius
|
double rad = 0; // radius
|
||||||
double rad2 = 0; // radius squared;
|
double rad2 = 0; // radius squared;
|
||||||
|
|
||||||
|
@ -120,7 +115,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
int i_max = -1;
|
int i_max = -1;
|
||||||
|
|
||||||
do
|
do
|
||||||
{ // now identify the point outside of the circle that has the greatest distance
|
{ // now identify the point outside of the circle that has the greatest distance
|
||||||
for (int i = 0; i < points.size();i++)
|
for (int i = 0; i < points.size();i++)
|
||||||
{
|
{
|
||||||
final Point p = points.get(i);
|
final Point p = points.get(i);
|
||||||
|
@ -145,10 +140,10 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
}
|
}
|
||||||
final double dist = Math.sqrt(dmax2);
|
final double dist = Math.sqrt(dmax2);
|
||||||
final double dd = 0.5 * (dist - rad) / dist;
|
final double dd = 0.5 * (dist - rad) / dist;
|
||||||
|
|
||||||
cx = cx + dd * dpx; // shift center toward point
|
cx = cx + dd * dpx; // shift center toward point
|
||||||
cy = cy + dd * dpy;
|
cy = cy + dd * dpy;
|
||||||
ccoslat = coslat(cy);
|
ccoslat = cr.cosIlat((int) cy);
|
||||||
|
|
||||||
final Point p = points.get(i_max); // calculate new radius to just include this point
|
final Point p = points.get(i_max); // calculate new radius to just include this point
|
||||||
final double dpix = (p.x - cx) * ccoslat;
|
final double dpix = (p.x - cx) * ccoslat;
|
||||||
|
@ -158,13 +153,13 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
i_max = -1;
|
i_max = -1;
|
||||||
}
|
}
|
||||||
while (true);
|
while (true);
|
||||||
|
|
||||||
ilon = (int) Math.round(cx);
|
ilon = (int) Math.round(cx);
|
||||||
ilat = (int) Math.round(cy);
|
ilat = (int) Math.round(cy);
|
||||||
dpx = cx - ilon; // rounding error
|
dpx = cx - ilon; // rounding error
|
||||||
dpy = cy - ilat;
|
dpy = cy - ilat;
|
||||||
// compensate rounding error of center-point
|
// compensate rounding error of center-point
|
||||||
radius = (rad + Math.sqrt(dpx * dpx + dpy * dpy)) * 0.000001;
|
radius = (rad + Math.sqrt(dpx * dpx + dpy * dpy)) * cr.ILATLNG_TO_LATLNG;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +169,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
* the polygon. For this test the winding-number algorithm is
|
* the polygon. 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.
|
||||||
*
|
*
|
||||||
* @param lon0 longitude of start point
|
* @param lon0 longitude of start point
|
||||||
* @param lat0 latitude of start point
|
* @param lat0 latitude of start point
|
||||||
* @param lon1 longitude of end point
|
* @param lon1 longitude of end point
|
||||||
|
@ -215,14 +210,14 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isOnLine( long px, long py, long p0x, long p0y, long p1x, long p1y )
|
public static boolean isOnLine( long px, long py, long p0x, long p0y, long p1x, long p1y )
|
||||||
{
|
{
|
||||||
final double v10x = px-p0x;
|
final double v10x = px-p0x;
|
||||||
final double v10y = py-p0y;
|
final double v10y = py-p0y;
|
||||||
final double v12x = p1x-p0x;
|
final double v12x = p1x-p0x;
|
||||||
final double v12y = p1y-p0y;
|
final double v12y = p1y-p0y;
|
||||||
|
|
||||||
if ( v10x == 0 ) // P0->P1 vertical?
|
if ( v10x == 0 ) // P0->P1 vertical?
|
||||||
{
|
{
|
||||||
if ( v10y == 0 ) // P0 == P1?
|
if ( v10y == 0 ) // P0 == P1?
|
||||||
|
@ -231,7 +226,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
}
|
}
|
||||||
if ( v12x != 0 ) // P1->P2 not vertical?
|
if ( v12x != 0 ) // P1->P2 not vertical?
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return ( v12y / v10y ) >= 1; // P1->P2 at least as long as P1->P0?
|
return ( v12y / v10y ) >= 1; // P1->P2 at least as long as P1->P0?
|
||||||
}
|
}
|
||||||
|
@ -239,7 +234,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
{
|
{
|
||||||
if ( v12y != 0 ) // P1->P2 not horizontal?
|
if ( v12y != 0 ) // P1->P2 not horizontal?
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// if ( P10x == 0 ) // P0 == P1? already tested
|
// if ( P10x == 0 ) // P0 == P1? already tested
|
||||||
return ( v12x / v10x ) >= 1; // P1->P2 at least as long as P1->P0?
|
return ( v12x / v10x ) >= 1; // P1->P2 at least as long as P1->P0?
|
||||||
|
@ -260,7 +255,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
their application. */
|
their application. */
|
||||||
/**
|
/**
|
||||||
* winding number test for a point in a polygon
|
* winding number test for a point in a polygon
|
||||||
*
|
*
|
||||||
* @param p a point
|
* @param p a point
|
||||||
* @param v list of vertex points forming a polygon. This polygon
|
* @param v list of vertex points forming a polygon. This polygon
|
||||||
* is implicitly closed connecting the last and first point.
|
* is implicitly closed connecting the last and first point.
|
||||||
|
@ -275,7 +270,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
final Point p0 = points.get(isClosed ? i_last : 0);
|
final Point p0 = points.get(isClosed ? i_last : 0);
|
||||||
long p0x = p0.x; // need to use long to avoid overflow in products
|
long p0x = p0.x; // need to use long to avoid overflow in products
|
||||||
long p0y = p0.y;
|
long p0y = p0.y;
|
||||||
|
|
||||||
for (int i = isClosed ? 0 : 1; i <= i_last; i++) // edge from v[i] to v[i+1]
|
for (int i = isClosed ? 0 : 1; i <= i_last; i++) // edge from v[i] to v[i+1]
|
||||||
{
|
{
|
||||||
final Point p1 = points.get(i);
|
final Point p1 = points.get(i);
|
||||||
|
@ -299,7 +294,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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)
|
||||||
|
@ -322,7 +317,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
their application. */
|
their application. */
|
||||||
/**
|
/**
|
||||||
* inSegment(): determine if a point is inside a segment
|
* inSegment(): determine if a point is inside a segment
|
||||||
*
|
*
|
||||||
* @param p a point
|
* @param p a point
|
||||||
* @param seg_p0 starting point of segment
|
* @param seg_p0 starting point of segment
|
||||||
* @param seg_p1 ending point of segment
|
* @param seg_p1 ending point of segment
|
||||||
|
@ -333,7 +328,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
{
|
{
|
||||||
final int sp0x = seg_p0.x;
|
final int sp0x = seg_p0.x;
|
||||||
final int sp1x = seg_p1.x;
|
final int sp1x = seg_p1.x;
|
||||||
|
|
||||||
if (sp0x != sp1x) // S is not vertical
|
if (sp0x != sp1x) // S is not vertical
|
||||||
{
|
{
|
||||||
final int px = p.x;
|
final int px = p.x;
|
||||||
|
@ -351,7 +346,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
final int sp0y = seg_p0.y;
|
final int sp0y = seg_p0.y;
|
||||||
final int sp1y = seg_p1.y;
|
final int sp1y = seg_p1.y;
|
||||||
final int py = p.y;
|
final int py = p.y;
|
||||||
|
|
||||||
if (sp0y <= py && py <= sp1y)
|
if (sp0y <= py && py <= sp1y)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -363,7 +358,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Copyright 2001 softSurfer, 2012 Dan Sunday, 2018 Norbert Truchsess
|
/* 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
|
||||||
|
@ -371,7 +366,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
resulting from its use. Users of this code must verify correctness for
|
resulting from its use. Users of this code must verify correctness for
|
||||||
their application. */
|
their application. */
|
||||||
/**
|
/**
|
||||||
* intersect2D_2Segments(): find the 2D intersection of 2 finite segments
|
* intersect2D_2Segments(): find the 2D intersection of 2 finite segments
|
||||||
* @param s1p0 start point of segment 1
|
* @param s1p0 start point of segment 1
|
||||||
* @param s1p1 end point of segment 1
|
* @param s1p1 end point of segment 1
|
||||||
* @param s2p0 start point of segment 2
|
* @param s2p0 start point of segment 2
|
||||||
|
@ -381,14 +376,14 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
* 2=overlap in segment from I0 to I1
|
* 2=overlap in segment from I0 to I1
|
||||||
*/
|
*/
|
||||||
private static int intersect2D_2Segments( final Point s1p0, final Point s1p1, final Point s2p0, final Point s2p1 )
|
private static int intersect2D_2Segments( final Point s1p0, final Point s1p1, final Point s2p0, final Point s2p1 )
|
||||||
{
|
{
|
||||||
final long ux = s1p1.x - s1p0.x; // vector u = S1P1-S1P0 (segment 1)
|
final long ux = s1p1.x - s1p0.x; // vector u = S1P1-S1P0 (segment 1)
|
||||||
final long uy = s1p1.y - s1p0.y;
|
final long uy = s1p1.y - s1p0.y;
|
||||||
final long vx = s2p1.x - s2p0.x; // vector v = S2P1-S2P0 (segment 2)
|
final long vx = s2p1.x - s2p0.x; // vector v = S2P1-S2P0 (segment 2)
|
||||||
final long vy = s2p1.y - s2p0.y;
|
final long vy = s2p1.y - s2p0.y;
|
||||||
final long wx = s1p0.x - s2p0.x; // vector w = S1P0-S2P0 (from start of segment 2 to start of segment 1
|
final long wx = s1p0.x - s2p0.x; // vector w = S1P0-S2P0 (from start of segment 2 to start of segment 1
|
||||||
final long wy = s1p0.y - s2p0.y;
|
final long wy = s1p0.y - s2p0.y;
|
||||||
|
|
||||||
final double d = ux * vy - uy * vx;
|
final double d = ux * vy - uy * vx;
|
||||||
|
|
||||||
// test if they are parallel (includes either being a point)
|
// test if they are parallel (includes either being a point)
|
||||||
|
@ -441,13 +436,13 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
||||||
}
|
}
|
||||||
t0 = t0<0? 0 : t0; // clip to min 0
|
t0 = t0<0? 0 : t0; // clip to min 0
|
||||||
t1 = t1>1? 1 : t1; // clip to max 1
|
t1 = t1>1? 1 : t1; // clip to max 1
|
||||||
|
|
||||||
return (t0 == t1) ? 1 : 2; // return 1 if intersect is a point
|
return (t0 == t1) ? 1 : 2; // return 1 if intersect is a point
|
||||||
}
|
}
|
||||||
|
|
||||||
// the segments are skew and may intersect in a point
|
// the segments are skew and may intersect in a point
|
||||||
// get the intersect parameter for S1
|
// get the intersect parameter for S1
|
||||||
|
|
||||||
final double sI = (vx * wy - vy * wx) / d;
|
final double sI = (vx * wy - vy * wx) / d;
|
||||||
if (sI < 0 || sI > 1) // no intersect with S1
|
if (sI < 0 || sI > 1) // no intersect with S1
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,6 +12,7 @@ import btools.mapaccess.OsmLinkHolder;
|
||||||
import btools.mapaccess.OsmNode;
|
import btools.mapaccess.OsmNode;
|
||||||
import btools.mapaccess.OsmTransferNode;
|
import btools.mapaccess.OsmTransferNode;
|
||||||
import btools.mapaccess.TurnRestriction;
|
import btools.mapaccess.TurnRestriction;
|
||||||
|
import btools.util.CheapRulerSingleton;
|
||||||
|
|
||||||
abstract class OsmPath implements OsmLinkHolder
|
abstract class OsmPath implements OsmLinkHolder
|
||||||
{
|
{
|
||||||
|
@ -344,7 +345,7 @@ abstract class OsmPath implements OsmLinkHolder
|
||||||
{
|
{
|
||||||
if ( rc.startDirectionValid )
|
if ( rc.startDirectionValid )
|
||||||
{
|
{
|
||||||
double dir = rc.startDirection.intValue() / 57.29578;
|
double dir = rc.startDirection.intValue() / CheapRulerSingleton.DEG_TO_RAD;
|
||||||
lon0 = lon1 - (int) ( 1000. * Math.sin( dir ) / rc.getCosLat() );
|
lon0 = lon1 - (int) ( 1000. * Math.sin( dir ) / rc.getCosLat() );
|
||||||
lat0 = lat1 - (int) ( 1000. * Math.cos( dir ) );
|
lat0 = lat1 - (int) ( 1000. * Math.cos( dir ) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import btools.expressions.BExpressionContextNode;
|
||||||
import btools.expressions.BExpressionContextWay;
|
import btools.expressions.BExpressionContextWay;
|
||||||
import btools.mapaccess.GeometryDecoder;
|
import btools.mapaccess.GeometryDecoder;
|
||||||
import btools.mapaccess.OsmLink;
|
import btools.mapaccess.OsmLink;
|
||||||
|
import btools.util.CheapRulerSingleton;
|
||||||
|
|
||||||
public final class RoutingContext
|
public final class RoutingContext
|
||||||
{
|
{
|
||||||
|
@ -247,6 +248,7 @@ public final class RoutingContext
|
||||||
try { ir = Integer.parseInt( s.substring( 4 ) ); }
|
try { ir = Integer.parseInt( s.substring( 4 ) ); }
|
||||||
catch( Exception e ) { /* ignore */ }
|
catch( Exception e ) { /* ignore */ }
|
||||||
}
|
}
|
||||||
|
// TODO[Phyks]
|
||||||
nogo.radius = ir / 110984.; // 6378000. / 57.3;
|
nogo.radius = ir / 110984.; // 6378000. / 57.3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -257,6 +259,7 @@ public final class RoutingContext
|
||||||
List<OsmNodeNamed> nogos = new ArrayList<OsmNodeNamed>();
|
List<OsmNodeNamed> nogos = new ArrayList<OsmNodeNamed>();
|
||||||
for( OsmNodeNamed nogo : nogopoints )
|
for( OsmNodeNamed nogo : nogopoints )
|
||||||
{
|
{
|
||||||
|
// TODO[Phyks]
|
||||||
int radiusInMeter = (int)(nogo.radius * 111894.);
|
int radiusInMeter = (int)(nogo.radius * 111894.);
|
||||||
boolean goodGuy = true;
|
boolean goodGuy = true;
|
||||||
for( OsmNodeNamed wp : waypoints )
|
for( OsmNodeNamed wp : waypoints )
|
||||||
|
@ -282,10 +285,11 @@ public final class RoutingContext
|
||||||
int n = nogopoints == null ? 0 : nogopoints.size();
|
int n = nogopoints == null ? 0 : nogopoints.size();
|
||||||
for( int i=0; i<n; i++ )
|
for( int i=0; i<n; i++ )
|
||||||
{
|
{
|
||||||
OsmNodeNamed nogo = nogopoints.get(i);
|
OsmNodeNamed nogo = nogopoints.get(i);
|
||||||
cs[0] += nogo.ilon;
|
cs[0] += nogo.ilon;
|
||||||
cs[1] += nogo.ilat;
|
cs[1] += nogo.ilat;
|
||||||
cs[2] += (long) ( nogo.radius*111894.*10.);
|
// TODO[Phyks]
|
||||||
|
cs[2] += (long) ( nogo.radius*111894.*10.);
|
||||||
}
|
}
|
||||||
return cs;
|
return cs;
|
||||||
}
|
}
|
||||||
|
@ -307,15 +311,13 @@ public final class RoutingContext
|
||||||
|
|
||||||
public int calcDistance( int lon1, int lat1, int lon2, int lat2 )
|
public int calcDistance( int lon1, int lat1, int lon2, int lat2 )
|
||||||
{
|
{
|
||||||
// TODO[Phyks]
|
CheapRulerSingleton cr = CheapRulerSingleton.getInstance();
|
||||||
double l = (lat2 - 90000000) * 0.00000001234134;
|
|
||||||
double l2 = l*l;
|
coslat = cr.cosIlat(lat2);
|
||||||
double l4 = l2*l2;
|
double coslat6 = coslat*cr.ILATLNG_TO_LATLNG;
|
||||||
coslat = 1.- l2 + l4 / 6.;
|
|
||||||
double coslat6 = coslat*0.000001;
|
|
||||||
|
|
||||||
double dx = (lon2 - lon1 ) * coslat6;
|
double dx = (lon2 - lon1 ) * coslat6;
|
||||||
double dy = (lat2 - lat1 ) * 0.000001;
|
double dy = (lat2 - lat1 ) * cr.ILATLNG_TO_LATLNG;
|
||||||
double d = Math.sqrt( dy*dy + dx*dx );
|
double d = Math.sqrt( dy*dy + dx*dx );
|
||||||
|
|
||||||
shortestmatch = false;
|
shortestmatch = false;
|
||||||
|
@ -326,9 +328,9 @@ public final class RoutingContext
|
||||||
{
|
{
|
||||||
OsmNodeNamed nogo = nogopoints.get(ngidx);
|
OsmNodeNamed nogo = nogopoints.get(ngidx);
|
||||||
double x1 = (lon1 - nogo.ilon) * coslat6;
|
double x1 = (lon1 - nogo.ilon) * coslat6;
|
||||||
double y1 = (lat1 - nogo.ilat) * 0.000001;
|
double y1 = (lat1 - nogo.ilat) * cr.ILATLNG_TO_LATLNG;
|
||||||
double x2 = (lon2 - nogo.ilon) * coslat6;
|
double x2 = (lon2 - nogo.ilon) * coslat6;
|
||||||
double y2 = (lat2 - nogo.ilat) * 0.000001;
|
double y2 = (lat2 - nogo.ilat) * cr.ILATLNG_TO_LATLNG;
|
||||||
double r12 = x1*x1 + y1*y1;
|
double r12 = x1*x1 + y1*y1;
|
||||||
double r22 = x2*x2 + y2*y2;
|
double r22 = x2*x2 + y2*y2;
|
||||||
double radius = Math.abs( r12 < r22 ? y1*dx - x1*dy : y2*dx - x2*dy ) / d;
|
double radius = Math.abs( r12 < r22 ? y1*dx - x1*dy : y2*dx - x2*dy ) / d;
|
||||||
|
@ -364,7 +366,7 @@ public final class RoutingContext
|
||||||
double xm = x2 - wayfraction*dx;
|
double xm = x2 - wayfraction*dx;
|
||||||
double ym = y2 - wayfraction*dy;
|
double ym = y2 - wayfraction*dy;
|
||||||
ilonshortest = (int)(xm / coslat6 + nogo.ilon);
|
ilonshortest = (int)(xm / coslat6 + nogo.ilon);
|
||||||
ilatshortest = (int)(ym / 0.000001 + nogo.ilat);
|
ilatshortest = (int)(ym / cr.ILATLNG_TO_LATLNG + nogo.ilat);
|
||||||
}
|
}
|
||||||
else if ( s1 > s2 )
|
else if ( s1 > s2 )
|
||||||
{
|
{
|
||||||
|
@ -396,14 +398,13 @@ public final class RoutingContext
|
||||||
lat1 = ilatshortest;
|
lat1 = ilatshortest;
|
||||||
}
|
}
|
||||||
dx = (lon2 - lon1 ) * coslat6;
|
dx = (lon2 - lon1 ) * coslat6;
|
||||||
dy = (lat2 - lat1 ) * 0.000001;
|
dy = (lat2 - lat1 ) * cr.ILATLNG_TO_LATLNG;
|
||||||
d = Math.sqrt( dy*dy + dx*dx );
|
d = Math.sqrt( dy*dy + dx*dx );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
double dd = d * 110984.; // 6378000. / 57.3;
|
return (int)(cr.distance(lon1, lat1, lon2, lat2) + 1.0 );
|
||||||
return (int)(dd + 1.0 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// assumes that calcDistance/calcCosAngle called in sequence, so coslat valid
|
// assumes that calcDistance/calcCosAngle called in sequence, so coslat valid
|
||||||
|
|
|
@ -9,6 +9,7 @@ import btools.mapaccess.OsmLink;
|
||||||
import btools.mapaccess.OsmNode;
|
import btools.mapaccess.OsmNode;
|
||||||
import btools.mapaccess.OsmTransferNode;
|
import btools.mapaccess.OsmTransferNode;
|
||||||
import btools.mapaccess.TurnRestriction;
|
import btools.mapaccess.TurnRestriction;
|
||||||
|
import btools.util.CheapRulerSingleton;
|
||||||
|
|
||||||
final class StdPath extends OsmPath
|
final class StdPath extends OsmPath
|
||||||
{
|
{
|
||||||
|
@ -183,6 +184,8 @@ final class StdPath extends OsmPath
|
||||||
// @Override
|
// @Override
|
||||||
protected void xxxaddAddionalPenalty(OsmTrack refTrack, boolean detailMode, OsmPath origin, OsmLink link, RoutingContext rc )
|
protected void xxxaddAddionalPenalty(OsmTrack refTrack, boolean detailMode, OsmPath origin, OsmLink link, RoutingContext rc )
|
||||||
{
|
{
|
||||||
|
CheapRulerSingleton cr = CheapRulerSingleton.getInstance();
|
||||||
|
|
||||||
byte[] description = link.descriptionBitmap;
|
byte[] description = link.descriptionBitmap;
|
||||||
if ( description == null ) throw new IllegalArgumentException( "null description for: " + link );
|
if ( description == null ) throw new IllegalArgumentException( "null description for: " + link );
|
||||||
|
|
||||||
|
@ -361,10 +364,10 @@ final class StdPath extends OsmPath
|
||||||
// apply a start-direction if appropriate (by faking the origin position)
|
// apply a start-direction if appropriate (by faking the origin position)
|
||||||
if ( lon0 == -1 && lat0 == -1 )
|
if ( lon0 == -1 && lat0 == -1 )
|
||||||
{
|
{
|
||||||
double coslat = Math.cos( ( lat1 - 90000000 ) * 0.00000001234134 );
|
double coslat = cr.cosIlat(lat1);
|
||||||
if ( rc.startDirectionValid && coslat > 0. )
|
if ( rc.startDirectionValid && coslat > 0. )
|
||||||
{
|
{
|
||||||
double dir = rc.startDirection.intValue() / 57.29578;
|
double dir = rc.startDirection.intValue() * 180. / Math.PI;
|
||||||
lon0 = lon1 - (int) ( 1000. * Math.sin( dir ) / coslat );
|
lon0 = lon1 - (int) ( 1000. * Math.sin( dir ) / coslat );
|
||||||
lat0 = lat1 - (int) ( 1000. * Math.cos( dir ) );
|
lat0 = lat1 - (int) ( 1000. * Math.cos( dir ) );
|
||||||
}
|
}
|
||||||
|
@ -646,7 +649,7 @@ final class StdPath extends OsmPath
|
||||||
if (rc.footMode )
|
if (rc.footMode )
|
||||||
{
|
{
|
||||||
// Use Tobler's hiking function for walking sections
|
// Use Tobler's hiking function for walking sections
|
||||||
speed = 6 * Math.exp(-3.5 * Math.abs( incline + 0.05)) / 3.6;
|
speed = 6 * exp(-3.5 * Math.abs( incline + 0.05)) / 3.6;
|
||||||
}
|
}
|
||||||
else if (rc.bikeMode)
|
else if (rc.bikeMode)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,11 +5,12 @@ import java.util.List;
|
||||||
import btools.codec.WaypointMatcher;
|
import btools.codec.WaypointMatcher;
|
||||||
import btools.mapaccess.OsmNode;
|
import btools.mapaccess.OsmNode;
|
||||||
import btools.mapaccess.OsmNodePairSet;
|
import btools.mapaccess.OsmNodePairSet;
|
||||||
|
import btools.util.CheapRulerSingleton;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* the WaypointMatcher is feeded by the decoder with geoemtries of ways that are
|
* the WaypointMatcher is feeded by the decoder with geoemtries of ways that are
|
||||||
* already check for allowed access according to the current routing profile
|
* already check for allowed access according to the current routing profile
|
||||||
*
|
*
|
||||||
* It matches these geometries against the list of waypoints to find the best
|
* It matches these geometries against the list of waypoints to find the best
|
||||||
* match for each waypoint
|
* match for each waypoint
|
||||||
*/
|
*/
|
||||||
|
@ -32,6 +33,7 @@ public final class WaypointMatcherImpl implements WaypointMatcher
|
||||||
this.islandPairs = islandPairs;
|
this.islandPairs = islandPairs;
|
||||||
for ( MatchedWaypoint mwp : waypoints )
|
for ( MatchedWaypoint mwp : waypoints )
|
||||||
{
|
{
|
||||||
|
// TODO[Phyks]
|
||||||
mwp.radius = maxDistance * 110984.; // 6378000. / 57.3;
|
mwp.radius = maxDistance * 110984.; // 6378000. / 57.3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,14 +42,12 @@ public final class WaypointMatcherImpl implements WaypointMatcher
|
||||||
{
|
{
|
||||||
// todo: bounding-box pre-filter
|
// todo: bounding-box pre-filter
|
||||||
|
|
||||||
double l = ( lat2 - 90000000 ) * 0.00000001234134;
|
CheapRulerSingleton cr = CheapRulerSingleton.getInstance();
|
||||||
double l2 = l * l;
|
double coslat = cr.cosIlat(lat2);
|
||||||
double l4 = l2 * l2;
|
double coslat6 = coslat * cr.ILATLNG_TO_LATLNG;
|
||||||
double coslat = 1. - l2 + l4 / 6.;
|
|
||||||
double coslat6 = coslat * 0.000001;
|
|
||||||
|
|
||||||
double dx = ( lon2 - lon1 ) * coslat6;
|
double dx = ( lon2 - lon1 ) * coslat6;
|
||||||
double dy = ( lat2 - lat1 ) * 0.000001;
|
double dy = ( lat2 - lat1 ) * cr.ILATLNG_TO_LATLNG;
|
||||||
double d = Math.sqrt( dy * dy + dx * dx );
|
double d = Math.sqrt( dy * dy + dx * dx );
|
||||||
if ( d == 0. )
|
if ( d == 0. )
|
||||||
return;
|
return;
|
||||||
|
@ -57,9 +57,9 @@ public final class WaypointMatcherImpl implements WaypointMatcher
|
||||||
OsmNodeNamed wp = mwp.waypoint;
|
OsmNodeNamed wp = mwp.waypoint;
|
||||||
|
|
||||||
double x1 = ( lon1 - wp.ilon ) * coslat6;
|
double x1 = ( lon1 - wp.ilon ) * coslat6;
|
||||||
double y1 = ( lat1 - wp.ilat ) * 0.000001;
|
double y1 = ( lat1 - wp.ilat ) * cr.ILATLNG_TO_LATLNG;
|
||||||
double x2 = ( lon2 - wp.ilon ) * coslat6;
|
double x2 = ( lon2 - wp.ilon ) * coslat6;
|
||||||
double y2 = ( lat2 - wp.ilat ) * 0.000001;
|
double y2 = ( lat2 - wp.ilat ) * cr.ILATLNG_TO_LATLNG;
|
||||||
double r12 = x1 * x1 + y1 * y1;
|
double r12 = x1 * x1 + y1 * y1;
|
||||||
double r22 = x2 * x2 + y2 * y2;
|
double r22 = x2 * x2 + y2 * y2;
|
||||||
double radius = Math.abs( r12 < r22 ? y1 * dx - x1 * dy : y2 * dx - x2 * dy ) / d;
|
double radius = Math.abs( r12 < r22 ? y1 * dx - x1 * dy : y2 * dx - x2 * dy ) / d;
|
||||||
|
@ -93,7 +93,7 @@ public final class WaypointMatcherImpl implements WaypointMatcher
|
||||||
double xm = x2 - wayfraction * dx;
|
double xm = x2 - wayfraction * dx;
|
||||||
double ym = y2 - wayfraction * dy;
|
double ym = y2 - wayfraction * dy;
|
||||||
mwp.crosspoint.ilon = (int) ( xm / coslat6 + wp.ilon );
|
mwp.crosspoint.ilon = (int) ( xm / coslat6 + wp.ilon );
|
||||||
mwp.crosspoint.ilat = (int) ( ym / 0.000001 + wp.ilat );
|
mwp.crosspoint.ilat = (int) ( ym / cr.ILATLNG_TO_LATLNG + wp.ilat );
|
||||||
}
|
}
|
||||||
else if ( s1 > s2 )
|
else if ( s1 > s2 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,12 +26,13 @@ import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import btools.router.OsmNogoPolygon.Point;
|
import btools.router.OsmNogoPolygon.Point;
|
||||||
|
import btools.util.CheapRulerSingleton;
|
||||||
|
|
||||||
public class OsmNogoPolygonTest {
|
public class OsmNogoPolygonTest {
|
||||||
|
|
||||||
static final int offset_x = 11000000;
|
static final int offset_x = 11000000;
|
||||||
static final int offset_y = 50000000;
|
static final int offset_y = 50000000;
|
||||||
|
|
||||||
static OsmNogoPolygon polygon;
|
static OsmNogoPolygon polygon;
|
||||||
static OsmNogoPolygon polyline;
|
static OsmNogoPolygon polyline;
|
||||||
|
|
||||||
|
@ -41,20 +42,11 @@ public class OsmNogoPolygonTest {
|
||||||
static int toOsmLon(double lon) {
|
static int toOsmLon(double lon) {
|
||||||
return (int)( ( lon + 180. ) *1000000. + 0.5)+offset_x; // see ServerHandler.readPosition()
|
return (int)( ( lon + 180. ) *1000000. + 0.5)+offset_x; // see ServerHandler.readPosition()
|
||||||
}
|
}
|
||||||
|
|
||||||
static int toOsmLat(double lat) {
|
static int toOsmLat(double lat) {
|
||||||
return (int)( ( lat + 90. ) *1000000. + 0.5)+offset_y;
|
return (int)( ( lat + 90. ) *1000000. + 0.5)+offset_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double coslat(int lat) // see RoutingContext.calcDistance()
|
|
||||||
{
|
|
||||||
final double l = (lat - 90000000) * 0.00000001234134; // 0.01234134 = Pi/(sqrt(2)*180)
|
|
||||||
final double l2 = l*l;
|
|
||||||
final double l4 = l2*l2;
|
|
||||||
// final double l6 = l4*l2;
|
|
||||||
return 1.- l2 + l4 / 6.; // - l6 / 90;
|
|
||||||
}
|
|
||||||
|
|
||||||
@BeforeClass
|
@BeforeClass
|
||||||
public static void setUp() throws Exception {
|
public static void setUp() throws Exception {
|
||||||
polygon = new OsmNogoPolygon(true);
|
polygon = new OsmNogoPolygon(true);
|
||||||
|
@ -66,20 +58,22 @@ public class OsmNogoPolygonTest {
|
||||||
polyline.addVertex(toOsmLon(lons[i]),toOsmLat(lats[i]));
|
polyline.addVertex(toOsmLon(lons[i]),toOsmLat(lats[i]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterClass
|
@AfterClass
|
||||||
public static void tearDown() throws Exception {
|
public static void tearDown() throws Exception {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCalcBoundingCircle() {
|
public void testCalcBoundingCircle() {
|
||||||
|
CheapRulerSingleton cr = CheapRulerSingleton.getInstance();
|
||||||
|
|
||||||
polygon.calcBoundingCircle();
|
polygon.calcBoundingCircle();
|
||||||
double r = polygon.radius;
|
double r = polygon.radius;
|
||||||
for (int i=0; i<lons.length; i++) {
|
for (int i=0; i<lons.length; i++) {
|
||||||
double py = toOsmLat(lats[i]);
|
double py = toOsmLat(lats[i]);
|
||||||
double dpx = (toOsmLon(lons[i]) - polygon.ilon) * coslat(polygon.ilat);
|
double dpx = (toOsmLon(lons[i]) - polygon.ilon) * cr.cosIlat(polygon.ilat);
|
||||||
double dpy = py - polygon.ilat;
|
double dpy = py - polygon.ilat;
|
||||||
double r1 = Math.sqrt(dpx * dpx + dpy * dpy) * 0.000001;
|
double r1 = Math.sqrt(dpx * dpx + dpy * dpy) * cr.ILATLNG_TO_LATLNG;
|
||||||
double diff = r-r1;
|
double diff = r-r1;
|
||||||
assertTrue("i: "+i+" r("+r+") >= r1("+r1+")", diff >= 0);
|
assertTrue("i: "+i+" r("+r+") >= r1("+r1+")", diff >= 0);
|
||||||
}
|
}
|
||||||
|
@ -87,9 +81,9 @@ public class OsmNogoPolygonTest {
|
||||||
r = polyline.radius;
|
r = polyline.radius;
|
||||||
for (int i=0; i<lons.length; i++) {
|
for (int i=0; i<lons.length; i++) {
|
||||||
double py = toOsmLat(lats[i]);
|
double py = toOsmLat(lats[i]);
|
||||||
double dpx = (toOsmLon(lons[i]) - polyline.ilon) * coslat(polyline.ilat);
|
double dpx = (toOsmLon(lons[i]) - polyline.ilon) * cr.cosIlat(polyline.ilat);
|
||||||
double dpy = py - polyline.ilat;
|
double dpy = py - polyline.ilat;
|
||||||
double r1 = Math.sqrt(dpx * dpx + dpy * dpy) * 0.000001;
|
double r1 = Math.sqrt(dpx * dpx + dpy * dpy) * cr.ILATLNG_TO_LATLNG;
|
||||||
double diff = r-r1;
|
double diff = r-r1;
|
||||||
assertTrue("i: "+i+" r("+r+") >= r1("+r1+")", diff >= 0);
|
assertTrue("i: "+i+" r("+r+") >= r1("+r1+")", diff >= 0);
|
||||||
}
|
}
|
||||||
|
@ -97,7 +91,7 @@ public class OsmNogoPolygonTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testIsWithin() {
|
public void testIsWithin() {
|
||||||
double[] plons = { 0.0, 0.5, 1.0, -1.5, -0.5, 1.0, 1.0, 0.5, 0.5, 0.5, };
|
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, };
|
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, true, true, true, true, true, };
|
boolean[] within = { true, false, false, false, false, true, true, true, true, true, };
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package btools.mapcreator;
|
package btools.mapcreator;
|
||||||
|
|
||||||
|
import btools.util.CheapRulerSingleton;
|
||||||
import btools.util.ReducedMedianFilter;
|
import btools.util.ReducedMedianFilter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,7 +27,7 @@ public class SrtmRaster
|
||||||
{
|
{
|
||||||
double lon = ilon / 1000000. - 180.;
|
double lon = ilon / 1000000. - 180.;
|
||||||
double lat = ilat / 1000000. - 90.;
|
double lat = ilat / 1000000. - 90.;
|
||||||
|
|
||||||
if ( usingWeights )
|
if ( usingWeights )
|
||||||
{
|
{
|
||||||
return getElevationFromShiftWeights( lon, lat );
|
return getElevationFromShiftWeights( lon, lat );
|
||||||
|
@ -50,7 +51,7 @@ public class SrtmRaster
|
||||||
+ ( wrow)*(1.-wcol)*get(row+1,col )
|
+ ( wrow)*(1.-wcol)*get(row+1,col )
|
||||||
+ (1.-wrow)*( wcol)*get(row ,col+1)
|
+ (1.-wrow)*( wcol)*get(row ,col+1)
|
||||||
+ ( wrow)*( wcol)*get(row+1,col+1);
|
+ ( wrow)*( wcol)*get(row+1,col+1);
|
||||||
// System.out.println( "eval=" + eval );
|
// System.out.println( "eval=" + eval );
|
||||||
return missingData ? Short.MIN_VALUE : (short)(eval*4);
|
return missingData ? Short.MIN_VALUE : (short)(eval*4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +61,7 @@ public class SrtmRaster
|
||||||
if ( e == Short.MIN_VALUE ) missingData = true;
|
if ( e == Short.MIN_VALUE ) missingData = true;
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
private short getElevationFromShiftWeights( double lon, double lat )
|
private short getElevationFromShiftWeights( double lon, double lat )
|
||||||
{
|
{
|
||||||
// calc lat-idx and -weight
|
// calc lat-idx and -weight
|
||||||
|
@ -68,7 +69,7 @@ public class SrtmRaster
|
||||||
alat /= 5.;
|
alat /= 5.;
|
||||||
int latIdx = (int)alat;
|
int latIdx = (int)alat;
|
||||||
double wlat = alat - latIdx;
|
double wlat = alat - latIdx;
|
||||||
|
|
||||||
double dcol = (lon - xllcorner)/cellsize;
|
double dcol = (lon - xllcorner)/cellsize;
|
||||||
double drow = (lat - yllcorner)/cellsize;
|
double drow = (lat - yllcorner)/cellsize;
|
||||||
int row = (int)drow;
|
int row = (int)drow;
|
||||||
|
@ -78,7 +79,7 @@ public class SrtmRaster
|
||||||
double dgy = (drow-row)*gridSteps;
|
double dgy = (drow-row)*gridSteps;
|
||||||
|
|
||||||
// System.out.println( "wrow=" + wrow + " wcol=" + wcol + " row=" + row + " col=" + col );
|
// System.out.println( "wrow=" + wrow + " wcol=" + wcol + " row=" + row + " col=" + col );
|
||||||
|
|
||||||
int gx = (int)(dgx);
|
int gx = (int)(dgx);
|
||||||
int gy = (int)(dgy);
|
int gy = (int)(dgy);
|
||||||
|
|
||||||
|
@ -89,12 +90,12 @@ public class SrtmRaster
|
||||||
double w01 = (1.-wx)*( wy);
|
double w01 = (1.-wx)*( wy);
|
||||||
double w10 = ( wx)*(1.-wy);
|
double w10 = ( wx)*(1.-wy);
|
||||||
double w11 = ( wx)*( wy);
|
double w11 = ( wx)*( wy);
|
||||||
|
|
||||||
Weights[][] w0 = getWeights( latIdx );
|
Weights[][] w0 = getWeights( latIdx );
|
||||||
Weights[][] w1 = getWeights( latIdx+1 );
|
Weights[][] w1 = getWeights( latIdx+1 );
|
||||||
|
|
||||||
missingData = false;
|
missingData = false;
|
||||||
|
|
||||||
double m0 = w00*getElevation( w0[gx ][gy ], row, col )
|
double m0 = w00*getElevation( w0[gx ][gy ], row, col )
|
||||||
+ w01*getElevation( w0[gx ][gy+1], row, col )
|
+ w01*getElevation( w0[gx ][gy+1], row, col )
|
||||||
+ w10*getElevation( w0[gx+1][gy ], row, col )
|
+ w10*getElevation( w0[gx+1][gy ], row, col )
|
||||||
|
@ -110,7 +111,7 @@ public class SrtmRaster
|
||||||
}
|
}
|
||||||
|
|
||||||
private ReducedMedianFilter rmf = new ReducedMedianFilter( 256 );
|
private ReducedMedianFilter rmf = new ReducedMedianFilter( 256 );
|
||||||
|
|
||||||
private double getElevation( Weights w, int row, int col )
|
private double getElevation( Weights w, int row, int col )
|
||||||
{
|
{
|
||||||
if ( missingData )
|
if ( missingData )
|
||||||
|
@ -186,7 +187,7 @@ public class SrtmRaster
|
||||||
return weights[ iy*nx + ix ];
|
return weights[ iy*nx + ix ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int gridSteps = 10;
|
private static int gridSteps = 10;
|
||||||
private static Weights[][][] allShiftWeights = new Weights[17][][];
|
private static Weights[][][] allShiftWeights = new Weights[17][][];
|
||||||
|
|
||||||
|
@ -208,15 +209,15 @@ public class SrtmRaster
|
||||||
System.out.println( "using filterCenterFraction = " + filterCenterFraction );
|
System.out.println( "using filterCenterFraction = " + filterCenterFraction );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// calculate interpolation weights from the overlap of a probe disc of given radius at given latitude
|
// calculate interpolation weights from the overlap of a probe disc of given radius at given latitude
|
||||||
// ( latIndex = 0 -> 0 deg, latIndex = 16 -> 80 degree)
|
// ( latIndex = 0 -> 0 deg, latIndex = 16 -> 80 degree)
|
||||||
|
|
||||||
private static Weights[][] getWeights( int latIndex )
|
private static Weights[][] getWeights( int latIndex )
|
||||||
{
|
{
|
||||||
int idx = latIndex < 16 ? latIndex : 16;
|
int idx = latIndex < 16 ? latIndex : 16;
|
||||||
|
|
||||||
Weights[][] res = allShiftWeights[idx];
|
Weights[][] res = allShiftWeights[idx];
|
||||||
if ( res == null )
|
if ( res == null )
|
||||||
{
|
{
|
||||||
|
@ -228,23 +229,24 @@ public class SrtmRaster
|
||||||
|
|
||||||
private static Weights[][] calcWeights( int latIndex )
|
private static Weights[][] calcWeights( int latIndex )
|
||||||
{
|
{
|
||||||
double coslat = Math.cos( latIndex * 5. / 57.3 );
|
CheapRulerSingleton cr = CheapRulerSingleton.getInstance();
|
||||||
|
double coslat = cr.cosLat(latIndex * 5.);
|
||||||
|
|
||||||
// radius in pixel units
|
// radius in pixel units
|
||||||
double ry = filterDiscRadius;
|
double ry = filterDiscRadius;
|
||||||
double rx = ry / coslat;
|
double rx = ry / coslat;
|
||||||
|
|
||||||
// gridsize is 2*radius + 1 cell
|
// gridsize is 2*radius + 1 cell
|
||||||
int nx = ((int)rx) *2 + 3;
|
int nx = ((int)rx) *2 + 3;
|
||||||
int ny = ((int)ry) *2 + 3;
|
int ny = ((int)ry) *2 + 3;
|
||||||
|
|
||||||
System.out.println( "nx="+ nx + " ny=" + ny );
|
System.out.println( "nx="+ nx + " ny=" + ny );
|
||||||
|
|
||||||
int mx = nx / 2; // mean pixels
|
int mx = nx / 2; // mean pixels
|
||||||
int my = ny / 2;
|
int my = ny / 2;
|
||||||
|
|
||||||
// create a matrix for the relative intergrid-position
|
// create a matrix for the relative intergrid-position
|
||||||
|
|
||||||
Weights[][] shiftWeights = new Weights[gridSteps+1][];
|
Weights[][] shiftWeights = new Weights[gridSteps+1][];
|
||||||
|
|
||||||
// loop the intergrid-position
|
// loop the intergrid-position
|
||||||
|
@ -262,11 +264,11 @@ public class SrtmRaster
|
||||||
shiftWeights[gx][gy] = weights;
|
shiftWeights[gx][gy] = weights;
|
||||||
|
|
||||||
double sampleStep = 0.001;
|
double sampleStep = 0.001;
|
||||||
|
|
||||||
for( double x = -1. + sampleStep/2.; x < 1.; x += sampleStep )
|
for( double x = -1. + sampleStep/2.; x < 1.; x += sampleStep )
|
||||||
{
|
{
|
||||||
double mx2 = 1. - x*x;
|
double mx2 = 1. - x*x;
|
||||||
|
|
||||||
int x_idx = (int)(x0 + x*rx);
|
int x_idx = (int)(x0 + x*rx);
|
||||||
|
|
||||||
for( double y = -1. + sampleStep/2.; y < 1.; y += sampleStep )
|
for( double y = -1. + sampleStep/2.; y < 1.; y += sampleStep )
|
||||||
|
|
|
@ -38,6 +38,7 @@ import btools.router.OsmTrack;
|
||||||
import btools.router.RoutingContext;
|
import btools.router.RoutingContext;
|
||||||
import btools.router.RoutingEngine;
|
import btools.router.RoutingEngine;
|
||||||
import btools.router.RoutingHelper;
|
import btools.router.RoutingHelper;
|
||||||
|
import btools.util.CheapRulerSingleton;
|
||||||
|
|
||||||
public class BRouterView extends View
|
public class BRouterView extends View
|
||||||
{
|
{
|
||||||
|
@ -247,7 +248,7 @@ public class BRouterView extends View
|
||||||
if ( fileName.equals( "lookups.dat" ) )
|
if ( fileName.equals( "lookups.dat" ) )
|
||||||
lookupsFound = true;
|
lookupsFound = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add a "last timeout" dummy profile
|
// add a "last timeout" dummy profile
|
||||||
File lastTimeoutFile = new File( modesDir + "/timeoutdata.txt" );
|
File lastTimeoutFile = new File( modesDir + "/timeoutdata.txt" );
|
||||||
long lastTimeoutTime = lastTimeoutFile.lastModified();
|
long lastTimeoutTime = lastTimeoutFile.lastModified();
|
||||||
|
@ -255,7 +256,7 @@ public class BRouterView extends View
|
||||||
{
|
{
|
||||||
profiles.add( 0, "<repeat timeout>" );
|
profiles.add( 0, "<repeat timeout>" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !lookupsFound )
|
if ( !lookupsFound )
|
||||||
{
|
{
|
||||||
throw new IllegalArgumentException( "The profile-directory " + profileDir + " does not contain the lookups.dat file."
|
throw new IllegalArgumentException( "The profile-directory " + profileDir + " does not contain the lookups.dat file."
|
||||||
|
@ -339,7 +340,7 @@ public class BRouterView extends View
|
||||||
{
|
{
|
||||||
msg = "Error reading waypoints: " + e.toString();
|
msg = "Error reading waypoints: " + e.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
int size = cor.allpoints.size();
|
int size = cor.allpoints.size();
|
||||||
if ( size < 1 )
|
if ( size < 1 )
|
||||||
msg = "coordinate source does not contain any waypoints!";
|
msg = "coordinate source does not contain any waypoints!";
|
||||||
|
@ -508,7 +509,8 @@ public class BRouterView extends View
|
||||||
centerLon = ( maxlon + minlon ) / 2;
|
centerLon = ( maxlon + minlon ) / 2;
|
||||||
centerLat = ( maxlat + minlat ) / 2;
|
centerLat = ( maxlat + minlat ) / 2;
|
||||||
|
|
||||||
double coslat = Math.cos( ( ( centerLat / 1000000. ) - 90. ) / 57.3 );
|
CheapRulerSingleton cr = CheapRulerSingleton.getInstance();
|
||||||
|
double coslat = cr.cosIlat(centerLat);
|
||||||
double difflon = maxlon - minlon;
|
double difflon = maxlon - minlon;
|
||||||
double difflat = maxlat - minlat;
|
double difflat = maxlat - minlat;
|
||||||
|
|
||||||
|
@ -522,7 +524,7 @@ public class BRouterView extends View
|
||||||
startTime = System.currentTimeMillis();
|
startTime = System.currentTimeMillis();
|
||||||
RoutingContext.prepareNogoPoints( nogoList );
|
RoutingContext.prepareNogoPoints( nogoList );
|
||||||
rc.nogopoints = nogoList;
|
rc.nogopoints = nogoList;
|
||||||
|
|
||||||
rc.memoryclass = memoryClass;
|
rc.memoryclass = memoryClass;
|
||||||
if ( memoryClass < 16 )
|
if ( memoryClass < 16 )
|
||||||
{
|
{
|
||||||
|
@ -532,9 +534,9 @@ public class BRouterView extends View
|
||||||
{
|
{
|
||||||
rc.memoryclass = 256;
|
rc.memoryclass = 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// for profile remote, use ref-track logic same as service interface
|
|
||||||
|
// for profile remote, use ref-track logic same as service interface
|
||||||
rc.rawTrackPath = rawTrackPath;
|
rc.rawTrackPath = rawTrackPath;
|
||||||
|
|
||||||
cr = new RoutingEngine( tracksDir + "/brouter", null, segmentDir, wpList, rc );
|
cr = new RoutingEngine( tracksDir + "/brouter", null, segmentDir, wpList, rc );
|
||||||
|
@ -642,7 +644,7 @@ public class BRouterView extends View
|
||||||
canvas.drawCircle( (float) x, (float) y, (float) ir, paint );
|
canvas.drawCircle( (float) x, (float) y, (float) ir, paint );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void paintLine( Canvas canvas, final int ilon0, final int ilat0, final int ilon1, final int ilat1, final Paint paint )
|
private void paintLine( Canvas canvas, final int ilon0, final int ilat0, final int ilon1, final int ilat1, final Paint paint )
|
||||||
{
|
{
|
||||||
final int lon0 = ilon0 - centerLon;
|
final int lon0 = ilon0 - centerLon;
|
||||||
|
@ -655,7 +657,7 @@ public class BRouterView extends View
|
||||||
final int y1 = imgh / 2 - (int) ( scaleLat * lat1 );
|
final int y1 = imgh / 2 - (int) ( scaleLat * lat1 );
|
||||||
canvas.drawLine( (float) x0, (float) y0, (float) x1, (float) y1, paint );
|
canvas.drawLine( (float) x0, (float) y0, (float) x1, (float) y1, paint );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void paintPolygon( Canvas canvas, OsmNogoPolygon p, int minradius )
|
private void paintPolygon( Canvas canvas, OsmNogoPolygon p, int minradius )
|
||||||
{
|
{
|
||||||
final int ir = (int) ( p.radius * 1000000. * scaleLat );
|
final int ir = (int) ( p.radius * 1000000. * scaleLat );
|
||||||
|
@ -666,7 +668,7 @@ public class BRouterView extends View
|
||||||
paint.setStyle( Paint.Style.STROKE );
|
paint.setStyle( Paint.Style.STROKE );
|
||||||
|
|
||||||
Point p0 = p.isClosed ? p.points.get(p.points.size()-1) : null;
|
Point p0 = p.isClosed ? p.points.get(p.points.size()-1) : null;
|
||||||
|
|
||||||
for ( final Point p1 : p.points )
|
for ( final Point p1 : p.points )
|
||||||
{
|
{
|
||||||
if (p0 != null)
|
if (p0 != null)
|
||||||
|
@ -865,7 +867,7 @@ public class BRouterView extends View
|
||||||
{
|
{
|
||||||
paintPolygon( canvas, (OsmNogoPolygon)n, 4 );
|
paintPolygon( canvas, (OsmNogoPolygon)n, 4 );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int color = 0xff0000;
|
int color = 0xff0000;
|
||||||
paintCircle( canvas, n, color, 4 );
|
paintCircle( canvas, n, color, 4 );
|
||||||
|
|
|
@ -15,9 +15,9 @@ public final class CheapRulerSingleton {
|
||||||
private static volatile CheapRulerSingleton instance = null;
|
private static volatile CheapRulerSingleton instance = null;
|
||||||
|
|
||||||
// Conversion constants
|
// Conversion constants
|
||||||
private final static double ILATLNG_TO_LATLNG = 1e-6; // From integer to degrees
|
public final static double ILATLNG_TO_LATLNG = 1e-6; // From integer to degrees
|
||||||
private final static int KILOMETERS_TO_METERS = 1000;
|
public final static int KILOMETERS_TO_METERS = 1000;
|
||||||
private final static double DEG_TO_RAD = Math.PI / 180.;
|
public final static double DEG_TO_RAD = Math.PI / 180.;
|
||||||
|
|
||||||
// Cosine cache constants
|
// Cosine cache constants
|
||||||
private final static int COS_CACHE_LENGTH = 8192;
|
private final static int COS_CACHE_LENGTH = 8192;
|
||||||
|
@ -58,7 +58,7 @@ public final class CheapRulerSingleton {
|
||||||
/**
|
/**
|
||||||
* Helper to compute the cosine of an integer latitude.
|
* Helper to compute the cosine of an integer latitude.
|
||||||
*/
|
*/
|
||||||
private double cosLat(int ilat) {
|
public double cosIlat(int ilat) {
|
||||||
double latDegrees = ilat * ILATLNG_TO_LATLNG;
|
double latDegrees = ilat * ILATLNG_TO_LATLNG;
|
||||||
if (ilat > 90000000) {
|
if (ilat > 90000000) {
|
||||||
// Use the symmetry of the cosine.
|
// Use the symmetry of the cosine.
|
||||||
|
@ -67,6 +67,16 @@ public final class CheapRulerSingleton {
|
||||||
return COS_CACHE[(int) (latDegrees * COS_CACHE_LENGTH / COS_CACHE_MAX_DEGREES)];
|
return COS_CACHE[(int) (latDegrees * COS_CACHE_LENGTH / COS_CACHE_MAX_DEGREES)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to compute the cosine of a latitude (in degrees).
|
||||||
|
*/
|
||||||
|
public double cosLat(double lat) {
|
||||||
|
if (lat < 0) {
|
||||||
|
lat += 90.;
|
||||||
|
}
|
||||||
|
return COS_CACHE[(int) (lat * COS_CACHE_LENGTH / COS_CACHE_MAX_DEGREES)];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute the distance (in meters) between two points represented by their
|
* Compute the distance (in meters) between two points represented by their
|
||||||
* (integer) latitude and longitude.
|
* (integer) latitude and longitude.
|
||||||
|
@ -80,7 +90,7 @@ public final class CheapRulerSingleton {
|
||||||
* Integer latitude is ((latitude in degrees) + 90) * 1e6.
|
* Integer latitude is ((latitude in degrees) + 90) * 1e6.
|
||||||
*/
|
*/
|
||||||
public double distance(int ilon1, int ilat1, int ilon2, int ilat2) {
|
public double distance(int ilon1, int ilat1, int ilon2, int ilat2) {
|
||||||
double cos = cosLat(ilat1);
|
double cos = cosIlat(ilat1);
|
||||||
double cos2 = 2 * cos * cos - 1;
|
double cos2 = 2 * cos * cos - 1;
|
||||||
double cos3 = 2 * cos * cos2 - cos;
|
double cos3 = 2 * cos * cos2 - cos;
|
||||||
double cos4 = 2 * cos * cos3 - cos2;
|
double cos4 = 2 * cos * cos3 - cos2;
|
||||||
|
|
Loading…
Reference in a new issue