Created
November 20, 2018 18:09
-
-
Save Phyks/2cc48655128f494e400e158ac73f214d to your computer and use it in GitHub Desktop.
Fast distance computation for BRouter
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class App { | |
public static void main(String [ ] args) | |
{ | |
int N_TESTS = 10000000; | |
double R = 6371000.; | |
double rad = Math.PI / 180; | |
double[] latlng1 = {48.8124, 2.3158}; | |
double[] latlng2 = {48.8204, 2.3210}; | |
double lon1, lon2, lat1, lat2, l, l2, l4, coslat, coslat6, dlat, dlon, sinDLat, sinDLon, a, c; | |
double distance = 0.; | |
System.out.println("Leaflet implementation:"); | |
long time = System.currentTimeMillis(); | |
for (int i = 0; i < N_TESTS; i++) { | |
lat1 = latlng1[0] * rad; | |
lat2 = latlng2[0] * rad; | |
sinDLat = Math.sin((latlng2[0] - latlng1[0]) * rad / 2); | |
sinDLon = Math.sin((latlng2[1] - latlng1[1]) * rad / 2); | |
a = sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon; | |
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); | |
distance = R * c; | |
} | |
System.out.println((System.currentTimeMillis() - time) / 1000.); | |
System.out.println(distance); | |
System.out.println("Current BRouter implementation:"); | |
time = System.currentTimeMillis(); | |
for (int i = 0; i < N_TESTS; i++) { | |
lon1 = latlng1[1] * 1e6; | |
lat1 = latlng1[0] * 1e6; | |
lon2 = latlng2[1] * 1e6; | |
lat2 = latlng2[0] * 1e6; | |
l = (lat2 - 90000000) * 0.00000001234134; | |
l2 = l * l; | |
l4 = l2 * l2; | |
coslat = 1. - l2 + l4 / 6.; | |
dlat = ( lat2 - lat1 ); | |
dlon = ( lon2 - lon1 ) * coslat; | |
distance = Math.sqrt( dlat * dlat + dlon * dlon ) * 0.110984; // 6378000. / 57.3; | |
distance = (int) ( distance + 1.0 ); | |
} | |
System.out.println((System.currentTimeMillis() - time) / 1000.); | |
System.out.println(distance); | |
System.out.println("Mapbox CheapRuler implementation:"); | |
time = System.currentTimeMillis(); | |
MathHelper mh = new MathHelper(); | |
for (int i = 0; i < N_TESTS; i++) { | |
double cos = mh.cos(latlng1[0] * Math.PI / 180); | |
double cos2 = 2 * cos * cos - 1; | |
double cos3 = 2 * cos * cos2 - cos; | |
double cos4 = 2 * cos * cos3 - cos2; | |
double cos5 = 2 * cos * cos4 - cos3; | |
// multipliers for converting longitude and latitude degrees into distance (http://1.usa.gov/1Wb1bv7) | |
double kx = (111.41513 * cos - 0.09455 * cos3 + 0.00012 * cos5); | |
double ky = (111.13209 - 0.56605 * cos2 + 0.0012 * cos4); | |
dlat = (latlng1[0] - latlng2[0]) * ky; | |
dlon = (latlng1[1] - latlng2[1]) * kx; | |
distance = Math.sqrt(dlat * dlat + dlon * dlon); // in km | |
} | |
System.out.println((System.currentTimeMillis() - time) / 1000.); | |
System.out.println(distance * 1000); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This code is coming from | |
// https://github.com/Bukkit/mc-dev/blob/master/net/minecraft/server/MathHelper.java | |
// and is therefore under Mojang copyright. | |
public class MathHelper { | |
private static double[] a = new double[65536]; | |
public static final double sin(double f) { | |
return a[(int) (f * 10430.378F) & '\uffff']; | |
} | |
public static final double cos(double f) { | |
return a[(int) (f * 10430.378F + 16384.0F) & '\uffff']; | |
} | |
static { | |
for (int i = 0; i < 65536; ++i) { | |
a[i] = Math.sin((double) i * 3.141592653589793D * 2.0D / 65536.0D); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment