Remove some duplicate codes and magic numbers

This commit is contained in:
Phyks (Lucas Verney) 2018-11-21 15:57:38 +01:00
parent c78b56645c
commit 5a62480bd3
9 changed files with 128 additions and 120 deletions

View file

@ -25,6 +25,8 @@ package btools.router;
import java.util.ArrayList;
import java.util.List;
import btools.util.CheapRulerSingleton;
public class OsmNogoPolygon extends OsmNodeNamed
{
public final static class Point
@ -55,15 +57,6 @@ public class OsmNogoPolygon extends OsmNodeNamed
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
* http://geomalgorithms.com/a08-_containers.html
@ -82,6 +75,8 @@ public class OsmNogoPolygon extends OsmNodeNamed
*/
public void calcBoundingCircle()
{
CheapRulerSingleton cr = CheapRulerSingleton.getInstance();
int cxmin, cxmax, cymin, cymax;
cxmin = cymin = Integer.MAX_VALUE;
cxmax = cymax = Integer.MIN_VALUE;
@ -110,7 +105,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
double cx = (cxmax+cxmin) / 2.0; // center of circle
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 rad2 = 0; // radius squared;
@ -148,7 +143,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
cx = cx + dd * dpx; // shift center toward point
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 double dpix = (p.x - cx) * ccoslat;
@ -164,7 +159,7 @@ public class OsmNogoPolygon extends OsmNodeNamed
dpx = cx - ilon; // rounding error
dpy = cy - ilat;
// 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;
}

View file

@ -12,6 +12,7 @@ import btools.mapaccess.OsmLinkHolder;
import btools.mapaccess.OsmNode;
import btools.mapaccess.OsmTransferNode;
import btools.mapaccess.TurnRestriction;
import btools.util.CheapRulerSingleton;
abstract class OsmPath implements OsmLinkHolder
{
@ -344,7 +345,7 @@ abstract class OsmPath implements OsmLinkHolder
{
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() );
lat0 = lat1 - (int) ( 1000. * Math.cos( dir ) );
}

View file

@ -16,6 +16,7 @@ import btools.expressions.BExpressionContextNode;
import btools.expressions.BExpressionContextWay;
import btools.mapaccess.GeometryDecoder;
import btools.mapaccess.OsmLink;
import btools.util.CheapRulerSingleton;
public final class RoutingContext
{
@ -247,6 +248,7 @@ public final class RoutingContext
try { ir = Integer.parseInt( s.substring( 4 ) ); }
catch( Exception e ) { /* ignore */ }
}
// TODO[Phyks]
nogo.radius = ir / 110984.; // 6378000. / 57.3;
}
}
@ -257,6 +259,7 @@ public final class RoutingContext
List<OsmNodeNamed> nogos = new ArrayList<OsmNodeNamed>();
for( OsmNodeNamed nogo : nogopoints )
{
// TODO[Phyks]
int radiusInMeter = (int)(nogo.radius * 111894.);
boolean goodGuy = true;
for( OsmNodeNamed wp : waypoints )
@ -285,6 +288,7 @@ public final class RoutingContext
OsmNodeNamed nogo = nogopoints.get(i);
cs[0] += nogo.ilon;
cs[1] += nogo.ilat;
// TODO[Phyks]
cs[2] += (long) ( nogo.radius*111894.*10.);
}
return cs;
@ -307,15 +311,13 @@ public final class RoutingContext
public int calcDistance( int lon1, int lat1, int lon2, int lat2 )
{
// TODO[Phyks]
double l = (lat2 - 90000000) * 0.00000001234134;
double l2 = l*l;
double l4 = l2*l2;
coslat = 1.- l2 + l4 / 6.;
double coslat6 = coslat*0.000001;
CheapRulerSingleton cr = CheapRulerSingleton.getInstance();
coslat = cr.cosIlat(lat2);
double coslat6 = coslat*cr.ILATLNG_TO_LATLNG;
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 );
shortestmatch = false;
@ -326,9 +328,9 @@ public final class RoutingContext
{
OsmNodeNamed nogo = nogopoints.get(ngidx);
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 y2 = (lat2 - nogo.ilat) * 0.000001;
double y2 = (lat2 - nogo.ilat) * cr.ILATLNG_TO_LATLNG;
double r12 = x1*x1 + y1*y1;
double r22 = x2*x2 + y2*y2;
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 ym = y2 - wayfraction*dy;
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 )
{
@ -396,14 +398,13 @@ public final class RoutingContext
lat1 = ilatshortest;
}
dx = (lon2 - lon1 ) * coslat6;
dy = (lat2 - lat1 ) * 0.000001;
dy = (lat2 - lat1 ) * cr.ILATLNG_TO_LATLNG;
d = Math.sqrt( dy*dy + dx*dx );
}
}
}
}
double dd = d * 110984.; // 6378000. / 57.3;
return (int)(dd + 1.0 );
return (int)(cr.distance(lon1, lat1, lon2, lat2) + 1.0 );
}
// assumes that calcDistance/calcCosAngle called in sequence, so coslat valid

View file

@ -9,6 +9,7 @@ import btools.mapaccess.OsmLink;
import btools.mapaccess.OsmNode;
import btools.mapaccess.OsmTransferNode;
import btools.mapaccess.TurnRestriction;
import btools.util.CheapRulerSingleton;
final class StdPath extends OsmPath
{
@ -183,6 +184,8 @@ final class StdPath extends OsmPath
// @Override
protected void xxxaddAddionalPenalty(OsmTrack refTrack, boolean detailMode, OsmPath origin, OsmLink link, RoutingContext rc )
{
CheapRulerSingleton cr = CheapRulerSingleton.getInstance();
byte[] description = link.descriptionBitmap;
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)
if ( lon0 == -1 && lat0 == -1 )
{
double coslat = Math.cos( ( lat1 - 90000000 ) * 0.00000001234134 );
double coslat = cr.cosIlat(lat1);
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 );
lat0 = lat1 - (int) ( 1000. * Math.cos( dir ) );
}
@ -646,7 +649,7 @@ final class StdPath extends OsmPath
if (rc.footMode )
{
// 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)
{

View file

@ -5,6 +5,7 @@ import java.util.List;
import btools.codec.WaypointMatcher;
import btools.mapaccess.OsmNode;
import btools.mapaccess.OsmNodePairSet;
import btools.util.CheapRulerSingleton;
/**
* the WaypointMatcher is feeded by the decoder with geoemtries of ways that are
@ -32,6 +33,7 @@ public final class WaypointMatcherImpl implements WaypointMatcher
this.islandPairs = islandPairs;
for ( MatchedWaypoint mwp : waypoints )
{
// TODO[Phyks]
mwp.radius = maxDistance * 110984.; // 6378000. / 57.3;
}
}
@ -40,14 +42,12 @@ public final class WaypointMatcherImpl implements WaypointMatcher
{
// todo: bounding-box pre-filter
double l = ( lat2 - 90000000 ) * 0.00000001234134;
double l2 = l * l;
double l4 = l2 * l2;
double coslat = 1. - l2 + l4 / 6.;
double coslat6 = coslat * 0.000001;
CheapRulerSingleton cr = CheapRulerSingleton.getInstance();
double coslat = cr.cosIlat(lat2);
double coslat6 = coslat * cr.ILATLNG_TO_LATLNG;
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 );
if ( d == 0. )
return;
@ -57,9 +57,9 @@ public final class WaypointMatcherImpl implements WaypointMatcher
OsmNodeNamed wp = mwp.waypoint;
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 y2 = ( lat2 - wp.ilat ) * 0.000001;
double y2 = ( lat2 - wp.ilat ) * cr.ILATLNG_TO_LATLNG;
double r12 = x1 * x1 + y1 * y1;
double r22 = x2 * x2 + y2 * y2;
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 ym = y2 - wayfraction * dy;
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 )
{

View file

@ -26,6 +26,7 @@ import org.junit.BeforeClass;
import org.junit.Test;
import btools.router.OsmNogoPolygon.Point;
import btools.util.CheapRulerSingleton;
public class OsmNogoPolygonTest {
@ -46,15 +47,6 @@ public class OsmNogoPolygonTest {
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
public static void setUp() throws Exception {
polygon = new OsmNogoPolygon(true);
@ -73,13 +65,15 @@ public class OsmNogoPolygonTest {
@Test
public void testCalcBoundingCircle() {
CheapRulerSingleton cr = CheapRulerSingleton.getInstance();
polygon.calcBoundingCircle();
double r = polygon.radius;
for (int i=0; i<lons.length; 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 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;
assertTrue("i: "+i+" r("+r+") >= r1("+r1+")", diff >= 0);
}
@ -87,9 +81,9 @@ public class OsmNogoPolygonTest {
r = polyline.radius;
for (int i=0; i<lons.length; 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 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;
assertTrue("i: "+i+" r("+r+") >= r1("+r1+")", diff >= 0);
}

View file

@ -1,5 +1,6 @@
package btools.mapcreator;
import btools.util.CheapRulerSingleton;
import btools.util.ReducedMedianFilter;
/**
@ -228,7 +229,8 @@ public class SrtmRaster
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
double ry = filterDiscRadius;

View file

@ -38,6 +38,7 @@ import btools.router.OsmTrack;
import btools.router.RoutingContext;
import btools.router.RoutingEngine;
import btools.router.RoutingHelper;
import btools.util.CheapRulerSingleton;
public class BRouterView extends View
{
@ -508,7 +509,8 @@ public class BRouterView extends View
centerLon = ( maxlon + minlon ) / 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 difflat = maxlat - minlat;

View file

@ -15,9 +15,9 @@ public final class CheapRulerSingleton {
private static volatile CheapRulerSingleton instance = null;
// Conversion constants
private final static double ILATLNG_TO_LATLNG = 1e-6; // From integer to degrees
private final static int KILOMETERS_TO_METERS = 1000;
private final static double DEG_TO_RAD = Math.PI / 180.;
public final static double ILATLNG_TO_LATLNG = 1e-6; // From integer to degrees
public final static int KILOMETERS_TO_METERS = 1000;
public final static double DEG_TO_RAD = Math.PI / 180.;
// Cosine cache constants
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.
*/
private double cosLat(int ilat) {
public double cosIlat(int ilat) {
double latDegrees = ilat * ILATLNG_TO_LATLNG;
if (ilat > 90000000) {
// 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)];
}
/**
* 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
* (integer) latitude and longitude.
@ -80,7 +90,7 @@ public final class CheapRulerSingleton {
* Integer latitude is ((latitude in degrees) + 90) * 1e6.
*/
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 cos3 = 2 * cos * cos2 - cos;
double cos4 = 2 * cos * cos3 - cos2;