Merge pull request #130 from Phyks/distance
Follow up on distance rework
This commit is contained in:
commit
d95a200070
21 changed files with 184 additions and 195 deletions
|
@ -5,7 +5,7 @@ package btools.codec;
|
|||
* range of these numbers to determine a noisy-bit count as a very simple
|
||||
* dictionary
|
||||
*
|
||||
* Adapted for 3-pass encoding (counters -> statistics -> encoding )
|
||||
* Adapted for 3-pass encoding (counters -> statistics -> encoding )
|
||||
* but doesn't do anything at pass1
|
||||
*/
|
||||
public final class NoisyDiffCoder
|
||||
|
|
|
@ -12,7 +12,7 @@ import btools.util.BitCoderContext;
|
|||
* It detects identical descriptions and sorts them
|
||||
* into a huffman-tree according to their frequencies
|
||||
*
|
||||
* Adapted for 3-pass encoding (counters -> statistics -> encoding )
|
||||
* Adapted for 3-pass encoding (counters -> statistics -> encoding )
|
||||
* but doesn't do anything at pass1
|
||||
*/
|
||||
public final class TagValueCoder
|
||||
|
|
|
@ -17,7 +17,7 @@ final class MatchedWaypoint
|
|||
public OsmNode node2;
|
||||
public OsmNodeNamed crosspoint;
|
||||
public OsmNodeNamed waypoint;
|
||||
public double radius;
|
||||
public double radius; // radius in meters
|
||||
public boolean hasUpdate;
|
||||
|
||||
public void writeToStream( DataOutput dos ) throws IOException
|
||||
|
|
|
@ -10,7 +10,7 @@ import btools.mapaccess.OsmNode;
|
|||
public class OsmNodeNamed extends OsmNode
|
||||
{
|
||||
public String name;
|
||||
public double radius; // radius of nogopoint
|
||||
public double radius; // radius of nogopoint (in meters)
|
||||
public boolean isNogo = false;
|
||||
|
||||
@Override
|
||||
|
|
|
@ -109,30 +109,25 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
|||
double dlat2m = lonlat2m[1];
|
||||
|
||||
double rad = 0; // radius
|
||||
double rad2 = 0; // radius squared;
|
||||
|
||||
double dpx = 0; // x-xomponent of vector from center to point
|
||||
double dpy = 0; // y-component
|
||||
double dmax2 = 0; // squared lenght of vector from center to point
|
||||
double dmax = 0; // length of vector from center to point
|
||||
int i_max = -1;
|
||||
|
||||
do
|
||||
{ // now identify the point outside of the circle that has the greatest distance
|
||||
for (int i = 0; i < points.size();i++)
|
||||
{
|
||||
// now identify the point outside of the circle that has the greatest distance
|
||||
for (int i = 0; i < points.size(); i++)
|
||||
{
|
||||
final Point p = points.get(i);
|
||||
final double dpix = (p.x - cx) * dlon2m;
|
||||
final double dpiy = (p.y - cy) * dlat2m;
|
||||
final double dist2 = dpix * dpix + dpiy * dpiy;
|
||||
if (dist2 <= rad2)
|
||||
final double dist = CheapRulerSingleton.distance(p.x, p.y, (int) cx, (int) cy);
|
||||
if (dist <= rad)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (dist2 > dmax2)
|
||||
if (dist > dmax)
|
||||
{
|
||||
dmax2 = dist2; // new maximum distance found
|
||||
dpx = dpix / dlon2m;
|
||||
dpy = dpiy / dlat2m;
|
||||
// new maximum distance found
|
||||
dmax = dist;
|
||||
i_max = i;
|
||||
}
|
||||
}
|
||||
|
@ -140,17 +135,13 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
|||
{
|
||||
break; // leave loop when no point outside the circle is found any more.
|
||||
}
|
||||
final double dist = Math.sqrt(dmax2);
|
||||
final double dd = 0.5 * (dist - rad) / dist;
|
||||
|
||||
cx += (int)(dd * dpx + 0.5); // shift center toward point
|
||||
cy += (int)(dd * dpy + 0.5);
|
||||
final double dd = 0.5 * (1 - rad / dmax);
|
||||
|
||||
final Point p = points.get(i_max); // calculate new radius to just include this point
|
||||
final double dpix = (p.x - cx) * dlon2m;
|
||||
final double dpiy = (p.y - cy) * dlat2m;
|
||||
dmax2 = rad2 = dpix * dpix + dpiy * dpiy;
|
||||
rad = Math.sqrt(rad2);
|
||||
cx += (int)(dd * (p.x - cx) + 0.5); // shift center toward point
|
||||
cy += (int)(dd * (p.y - cy) + 0.5);
|
||||
|
||||
dmax = rad = CheapRulerSingleton.distance(p.x, p.y, (int) cx, (int) cy);
|
||||
i_max = -1;
|
||||
}
|
||||
while (true);
|
||||
|
@ -254,10 +245,9 @@ public class OsmNogoPolygon extends OsmNodeNamed
|
|||
/**
|
||||
* winding number test for a point in a polygon
|
||||
*
|
||||
* @param p a point
|
||||
* @param v list of vertex points forming a polygon. This polygon
|
||||
* is implicitly closed connecting the last and first point.
|
||||
* @return the winding number (=0 only when P is outside)
|
||||
* @param px longitude of the point to check
|
||||
* @param py latitude of the point to check
|
||||
* @return a boolean whether the point is within the polygon or not.
|
||||
*/
|
||||
public boolean isWithin(final long px, final long py)
|
||||
{
|
||||
|
|
|
@ -346,8 +346,9 @@ abstract class OsmPath implements OsmLinkHolder
|
|||
if ( rc.startDirectionValid )
|
||||
{
|
||||
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 ) );
|
||||
double[] lonlat2m = CheapRulerSingleton.getLonLatToMeterScales( (lon0 + lat1) >> 1 );
|
||||
lon0 = lon1 - (int) ( 1000. * Math.sin( dir ) / lonlat2m[0] );
|
||||
lat0 = lat1 - (int) ( 1000. * Math.cos( dir ) / lonlat2m[1] );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -193,7 +193,6 @@ public final class RoutingContext
|
|||
public Integer startDirection;
|
||||
public boolean startDirectionValid;
|
||||
|
||||
private double coslat;
|
||||
private double cosangle;
|
||||
public boolean nogomatch = false;
|
||||
public boolean isEndpoint = false;
|
||||
|
@ -248,8 +247,8 @@ public final class RoutingContext
|
|||
try { ir = Integer.parseInt( s.substring( 4 ) ); }
|
||||
catch( Exception e ) { /* ignore */ }
|
||||
}
|
||||
// TODO[Phyks]
|
||||
nogo.radius = ir / 110984.; // 6378000. / 57.3;
|
||||
// Radius of the nogo point in meters
|
||||
nogo.radius = ir;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -259,12 +258,10 @@ 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 )
|
||||
{
|
||||
if ( wp.calcDistance( nogo ) < radiusInMeter
|
||||
if ( wp.calcDistance( nogo ) < nogo.radius
|
||||
&& (!(nogo instanceof OsmNogoPolygon)
|
||||
|| (((OsmNogoPolygon)nogo).isClosed
|
||||
? ((OsmNogoPolygon)nogo).isWithin(wp.ilon, wp.ilat)
|
||||
|
@ -288,6 +285,7 @@ public final class RoutingContext
|
|||
OsmNodeNamed nogo = nogopoints.get(i);
|
||||
cs[0] += nogo.ilon;
|
||||
cs[1] += nogo.ilat;
|
||||
// 10 is an arbitrary constant to get sub-integer precision in the checksum
|
||||
cs[2] += (long) ( nogo.radius*10.);
|
||||
}
|
||||
return cs;
|
||||
|
@ -342,7 +340,7 @@ public final class RoutingContext
|
|||
if ( s2 > 0. )
|
||||
{
|
||||
radius = Math.sqrt( s1 < s2 ? r12 : r22 );
|
||||
if ( radius > nogo.radius ) continue; // 20m ^ 2
|
||||
if ( radius > nogo.radius ) continue;
|
||||
}
|
||||
if ( nogo.isNogo )
|
||||
{
|
||||
|
@ -404,28 +402,23 @@ public final class RoutingContext
|
|||
return (int)(d + 1.0 );
|
||||
}
|
||||
|
||||
// assumes that calcDistance/calcCosAngle called in sequence, so coslat valid
|
||||
public double getCosAngle()
|
||||
{
|
||||
return cosangle;
|
||||
}
|
||||
|
||||
public double getCosLat()
|
||||
{
|
||||
return coslat;
|
||||
}
|
||||
|
||||
public double calcAngle( int lon0, int lat0, int lon1, int lat1, int lon2, int lat2 )
|
||||
{
|
||||
double dlat1 = (lat1 - lat0);
|
||||
double dlon1 = (lon1 - lon0) * coslat;
|
||||
double dlat2 = (lat2 - lat1);
|
||||
double dlon2 = (lon2 - lon1) * coslat;
|
||||
double[] lonlat2m = CheapRulerSingleton.getLonLatToMeterScales( lat1 );
|
||||
double dy10 = (lat1 - lat0) * lonlat2m[1];
|
||||
double dx10 = (lon1 - lon0) * lonlat2m[0];
|
||||
double dy21 = (lat2 - lat1) * lonlat2m[1];
|
||||
double dx21 = (lon2 - lon1) * lonlat2m[0];
|
||||
|
||||
double dd = Math.sqrt( (dlat1*dlat1 + dlon1*dlon1)*(dlat2*dlat2 + dlon2*dlon2) );
|
||||
double dd = Math.sqrt( (dx10*dx10 + dy10*dy10)*(dx21*dx21 + dy21*dy21) );
|
||||
if ( dd == 0. ) { cosangle = 1.; return 0.; }
|
||||
double sinp = (dlat1*dlon2 - dlon1*dlat2)/dd;
|
||||
double cosp = (dlat1*dlat2 + dlon1*dlon2)/dd;
|
||||
double sinp = (dy10*dy21 - dx10*dx21)/dd;
|
||||
double cosp = (dy10*dy21 + dx10*dx21)/dd;
|
||||
cosangle = cosp;
|
||||
|
||||
double p;
|
||||
|
|
|
@ -25,6 +25,9 @@ public final class SearchBoundary
|
|||
|
||||
int direction;
|
||||
|
||||
/**
|
||||
* @param radius Search radius in meters.
|
||||
*/
|
||||
public SearchBoundary( OsmNode n, int radius, int direction )
|
||||
{
|
||||
this.radius = radius;
|
||||
|
|
|
@ -33,8 +33,7 @@ public final class WaypointMatcherImpl implements WaypointMatcher
|
|||
this.islandPairs = islandPairs;
|
||||
for ( MatchedWaypoint mwp : waypoints )
|
||||
{
|
||||
// TODO[Phyks]
|
||||
mwp.radius = maxDistance * 110984.; // 6378000. / 57.3;
|
||||
mwp.radius = maxDistance;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,6 +48,7 @@ public final class WaypointMatcherImpl implements WaypointMatcher
|
|||
double dx = ( lon2 - lon1 ) * dlon2m;
|
||||
double dy = ( lat2 - lat1 ) * dlat2m;
|
||||
double d = Math.sqrt( dy * dy + dx * dx );
|
||||
|
||||
if ( d == 0. )
|
||||
return;
|
||||
|
||||
|
|
|
@ -647,7 +647,7 @@ public abstract class BExpressionContext implements IByteArrayUnifier
|
|||
|
||||
/**
|
||||
* special hack for yes/proposed relations:
|
||||
* add a lookup value if not yet a smaller, >1 value was added
|
||||
* add a lookup value if not yet a smaller, > 1 value was added
|
||||
* add a 2=yes if the provided value is out of range
|
||||
* value-index means here 0=unknown, 1=other, 2=yes, 3=proposed
|
||||
*/
|
||||
|
|
|
@ -60,10 +60,10 @@ public final class BitReadBuffer
|
|||
/**
|
||||
* decode a small number with a variable bit length
|
||||
* (poor mans huffman tree)
|
||||
* 1 -> 0
|
||||
* 01 -> 1 + following 1-bit word ( 1..2 )
|
||||
* 001 -> 3 + following 2-bit word ( 3..6 )
|
||||
* 0001 -> 7 + following 3-bit word ( 7..14 ) etc.
|
||||
* {@code 1 -> 0}
|
||||
* {@code 01 -> 1} + following 1-bit word ( 1..2 )
|
||||
* {@code 001 -> 3} + following 2-bit word ( 3..6 )
|
||||
* {@code 0001 -> 7} + following 3-bit word ( 7..14 ) etc.
|
||||
*/
|
||||
public int decodeInt()
|
||||
{
|
||||
|
|
|
@ -23,12 +23,13 @@ public final class BitWriteBuffer
|
|||
/**
|
||||
* encode a distance with a variable bit length
|
||||
* (poor mans huffman tree)
|
||||
* 1 -> 0
|
||||
* 01 -> 1 + following 1-bit word ( 1..2 )
|
||||
* 001 -> 3 + following 2-bit word ( 3..6 )
|
||||
* 0001 -> 7 + following 3-bit word ( 7..14 ) etc.
|
||||
* {@code 1 -> 0}
|
||||
* {@code 01 -> 1} + following 1-bit word ( 1..2 )
|
||||
* {@code 001 -> 3} + following 2-bit word ( 3..6 )
|
||||
* {@code 0001 -> 7} + following 3-bit word ( 7..14 ) etc.
|
||||
*
|
||||
* @see btools.util.BitCoderContext#decodeVarBits
|
||||
*
|
||||
* @see #decodeVarBits
|
||||
*/
|
||||
public void encodeInt( int value )
|
||||
{
|
||||
|
|
|
@ -10,7 +10,7 @@ import java.util.PriorityQueue;
|
|||
* It detects identical sets and sorts them
|
||||
* into a huffman-tree according to their frequencies
|
||||
*
|
||||
* Adapted for 3-pass encoding (counters -> statistics -> encoding )
|
||||
* Adapted for 3-pass encoding (counters -> statistics -> encoding )
|
||||
* but doesn't do anything at pass1
|
||||
*/
|
||||
public abstract class HuffmanTreeEncoder<V>
|
||||
|
|
|
@ -10,7 +10,7 @@ import java.util.PriorityQueue;
|
|||
* It detects identical sets and sorts them
|
||||
* into a huffman-tree according to their frequencies
|
||||
*
|
||||
* Adapted for 3-pass encoding (counters -> statistics -> encoding )
|
||||
* Adapted for 3-pass encoding (counters -> statistics -> encoding )
|
||||
* but doesn't do anything at pass1
|
||||
*/
|
||||
public final class TagSetEncoder
|
||||
|
|
|
@ -635,7 +635,9 @@ public class BRouterView extends View
|
|||
int lat = n.ilat - centerLat;
|
||||
int x = imgw / 2 + (int) ( scaleLon * lon );
|
||||
int y = imgh / 2 - (int) ( scaleLat * lat );
|
||||
int ir = (int) ( n.radius * 1000000. * scaleLat );
|
||||
|
||||
double[] lonlat2m = CheapRulerSingleton.getLonLatToMeterScales( centerLat );
|
||||
int ir = (int) ( n.radius * scaleLat / lonlat2m[1]);
|
||||
if ( ir > minradius )
|
||||
{
|
||||
Paint paint = new Paint();
|
||||
|
@ -660,7 +662,8 @@ public class BRouterView extends View
|
|||
|
||||
private void paintPolygon( Canvas canvas, OsmNogoPolygon p, int minradius )
|
||||
{
|
||||
final int ir = (int) ( p.radius * 1000000. * scaleLat );
|
||||
double[] lonlat2m = CheapRulerSingleton.getLonLatToMeterScales( centerLat );
|
||||
final int ir = (int) ( p.radius * scaleLat / lonlat2m[1] );
|
||||
if ( ir > minradius )
|
||||
{
|
||||
Paint paint = new Paint();
|
||||
|
|
|
@ -25,8 +25,8 @@ import java.util.List;
|
|||
* format = [kml|gpx|geojson] (optional, default gpx)
|
||||
*
|
||||
* Example URLs:
|
||||
* http://localhost:17777/brouter?lonlats=8.799297,49.565883|8.811764,49.563606&nogos=&profile=trekking&alternativeidx=0&format=gpx
|
||||
* http://localhost:17777/brouter?lonlats=1.1,1.2|2.1,2.2|3.1,3.2|4.1,4.2&nogos=-1.1,-1.2,1|-2.1,-2.2,2&profile=shortest&alternativeidx=1&format=kml
|
||||
* {@code http://localhost:17777/brouter?lonlats=8.799297,49.565883|8.811764,49.563606&nogos=&profile=trekking&alternativeidx=0&format=gpx}
|
||||
* {@code http://localhost:17777/brouter?lonlats=1.1,1.2|2.1,2.2|3.1,3.2|4.1,4.2&nogos=-1.1,-1.2,1|-2.1,-2.2,2&profile=shortest&alternativeidx=1&format=kml}
|
||||
*
|
||||
*/
|
||||
public class ServerHandler extends RequestHandler {
|
||||
|
|
|
@ -34,10 +34,10 @@ public class BitCoderContext
|
|||
/**
|
||||
* encode a distance with a variable bit length
|
||||
* (poor mans huffman tree)
|
||||
* 1 -> 0
|
||||
* 01 -> 1 + following 1-bit word ( 1..2 )
|
||||
* 001 -> 3 + following 2-bit word ( 3..6 )
|
||||
* 0001 -> 7 + following 3-bit word ( 7..14 ) etc.
|
||||
* {@code 1 -> 0}
|
||||
* {@code 01 -> 1} + following 1-bit word ( 1..2 )
|
||||
* {@code 001 -> 3} + following 2-bit word ( 3..6 )
|
||||
* {@code 0001 -> 7} + following 3-bit word ( 7..14 ) etc.
|
||||
*
|
||||
* @see #decodeVarBits
|
||||
*/
|
||||
|
|
|
@ -17,7 +17,7 @@ public final class ByteArrayUnifier implements IByteArrayUnifier
|
|||
* Unify a byte array in order to reuse instances when possible.
|
||||
* The byte arrays are assumed to be treated as immutable,
|
||||
* allowing the reuse
|
||||
* @param the byte array to unify
|
||||
* @param ab the byte array to unify
|
||||
* @return the cached instance or the input instanced if not cached
|
||||
*/
|
||||
public byte[] unify( byte[] ab )
|
||||
|
|
|
@ -17,10 +17,10 @@ public final class CheapRulerSingleton {
|
|||
public final static int KILOMETERS_TO_METERS = 1000;
|
||||
public final static double DEG_TO_RAD = Math.PI / 180.;
|
||||
|
||||
// Cosine cache constants
|
||||
// Scale cache constants
|
||||
private final static int SCALE_CACHE_LENGTH = 1800;
|
||||
private final static int SCALE_CACHE_INCREMENT = 100000;
|
||||
// COS_CACHE_LENGTH cached values between 0 and COS_CACHE_MAX_DEGREES degrees.
|
||||
// SCALE_CACHE_LENGTH cached values between 0 and COS_CACHE_MAX_DEGREES degrees.
|
||||
private final static double[][] SCALE_CACHE = new double[SCALE_CACHE_LENGTH][];
|
||||
|
||||
/**
|
||||
|
@ -33,7 +33,7 @@ public final class CheapRulerSingleton {
|
|||
}
|
||||
|
||||
private static double[] calcKxKyFromILat(int ilat) {
|
||||
double lat = DEG_TO_RAD*(ilat-90000000)/1000000.;
|
||||
double lat = DEG_TO_RAD*ilat*ILATLNG_TO_LATLNG - 90;
|
||||
double cos = Math.cos(lat);
|
||||
double cos2 = 2 * cos * cos - 1;
|
||||
double cos3 = 2 * cos * cos2 - cos;
|
||||
|
@ -49,9 +49,9 @@ public final class CheapRulerSingleton {
|
|||
}
|
||||
|
||||
/**
|
||||
* Calculate the degree->meter scale for given latitude
|
||||
* Calculate the degree->meter scale for given latitude
|
||||
*
|
||||
* @result [lon->meter,lat->meter]
|
||||
* @return [lon->meter,lat->meter]
|
||||
*/
|
||||
public static double[] getLonLatToMeterScales( int ilat ) {
|
||||
return SCALE_CACHE[ ilat / SCALE_CACHE_INCREMENT ];
|
||||
|
@ -65,9 +65,11 @@ public final class CheapRulerSingleton {
|
|||
* @param ilat1 Integer latitude for the start point, this is (latitude + 90) * 1e6.
|
||||
* @param ilon2 Integer longitude for the end point, this is (longitude + 180) * 1e6.
|
||||
* @param ilat2 Integer latitude for the end point, this is (latitude + 90) * 1e6.
|
||||
* @return The distance between the two points, in meters.
|
||||
*
|
||||
* @note Integer longitude is ((longitude in degrees) + 180) * 1e6.
|
||||
* Integer latitude is ((latitude in degrees) + 90) * 1e6.
|
||||
* Note:
|
||||
* Integer longitude is ((longitude in degrees) + 180) * 1e6.
|
||||
* Integer latitude is ((latitude in degrees) + 90) * 1e6.
|
||||
*/
|
||||
public static double distance(int ilon1, int ilat1, int ilon2, int ilat2) {
|
||||
double[] kxky = getLonLatToMeterScales( ( ilat1 + ilat2 ) >> 1 );
|
||||
|
|
|
@ -31,8 +31,6 @@ public class DenseLongMap
|
|||
* Creates a DenseLongMap for the default block size
|
||||
* ( 512 bytes per bitplane, covering a key range of 4096 keys )
|
||||
* Note that one value range is limited to 0..254
|
||||
*
|
||||
* @param valuebits number of bits to use per value
|
||||
*/
|
||||
public DenseLongMap()
|
||||
{
|
||||
|
|
|
@ -133,10 +133,8 @@ public final class SortedHeap<V>
|
|||
/**
|
||||
* add a key value pair to the heap
|
||||
*
|
||||
* @param id
|
||||
* the key to insert
|
||||
* @param value
|
||||
* the value to insert object
|
||||
* @param key the key to insert
|
||||
* @param value the value to insert object
|
||||
*/
|
||||
public void add( int key, V value )
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue