I have a large number of Longitude and Latitudes and I want to quickly find out which ones are within say a 5km radius of a certain Longitude Latitude.
Instead of using a datastructure (Which would be overkill), I should be able to perform n do products very quickly. I've just done something wrong and can't seem to see what.
I have been trying to implement this in Java:
final List<CoOrds> coOrds = Create20x20Grid();
// Determine point X (centre of earth)
final Vector2 X = new Vector2(0,0);
// My CoOrd I want to check
final double srclon = coOrds.get(0).getLongitude();
final double srclat = coOrds.get(0).getLatitude();
final Vector2 A = new Vector2(srclon, srclat, true);
final double brng = 0;
final double d = 5;
final double R = 6371.1;
double dist = 0;
dist = d / R; // convert dist to angular distance in radians
final double lat1 = Math.toRadians(srclat);
final double lon1 = Math.toRadians(srclon);
final double lat2 = Math.asin(Math.sin(lat1) * Math.cos(dist)+ Math.cos(lat1) * Math.sin(dist) * Math.cos(brng));
double lon2 = lon1 + Math.atan2(Math.sin(brng) * Math.sin(dist) * Math.cos(lat1),Math.cos(dist) - Math.sin(lat1) * Math.sin(lat2));
// normalise to -180..+180º
lon2 = (lon2 + 3 * Math.PI) % (2 * Math.PI) - Math.PI;
//Create another point which is the distance is d away from your point
final Vector2 B = new Vector2(Math.toDegrees(lon2),Math.toDegrees(lat2), true);
// Create a vector from X->A
final Vector2 X_A = new Vector2((A.getX() - X.getX()),(A.getY() - X.getY()));
// Create a vector from X->B
final Vector2 X_B = new Vector2((B.getX() - X.getX()),(B.getY() - X.getY()));
// Normalize XA
final Vector2 nX_A = X_A.normalize();
// Normalize XB
final Vector2 nX_B = X_B.normalize();
// Calculate the Dot Product
final Double Alpha = nX_A.dot(nX_B);
int count = 0;
for (final CoOrds c : coOrds) {
final Vector2 P = c.getPosition();
final Vector2 X_P = new Vector2((P.getX() - X.getX()),(P.getY() - X.getY()));
final Vector2 nX_P = X_P.normalize());
final Double Beta = nX_A.dot(nX_P);
if (Beta < Alpha) {
System.out.println(count + " -- " + Beta + " : " + Alpha);
count++;
}
}
System.out.println("Number of CoOrds within Distance : " + count);
The new point P is correct as I've loaded it into Google Maps, but I am not entirely sure if I have the calculations correct.
I have created a custom Vector2 class, which stores the Longitude and Latitude. It also coverts them to Cartesian:
private void convertSphericalToCartesian(final double latitude, final double longitude) {
x = (earthRadius * Math.cos(latitude) * Math.cos(longitude)) ;
y = (earthRadius * Math.cos(latitude) * Math.sin(longitude)) ;
}
The Dot Product:
public double dot(final Vector2 v2) {
return ((getX() * v2.getX()) + (getY() * v2.getY()));
}
The Normalize:
public Vector2 normalize() {
final double num2 = (getX() * getX()) + (getY() * getY());
final double num = 1d / Math.sqrt(num2);
double a = x;
double b = y;
a *= num;
b *= num;
return new Vector2(a, b);
}
Any help with this would be really appreciated
I used this website: http://www.movable-type.co.uk/scripts/latlong.html To help me calculate point B.
I used this website : http://rbrundritt.wordpress.com/2008/10/14/conversion-between-spherical-and-cartesian-coordinates-systems/ To help me transform Spherical CoOrdinates to Cartesian CoOrdinates.
Thanks
[EDIT]
The test case I am currently running is:
0-0-0
2-2-0
1-2-0
Where the above is a grid of 9 points. The point I am checking is "1". I expect it to return all the points "2". But it is returning all the points in the grid. I have manually checked the distances on Google Maps and it should only be returning the points "2".
Thanks
From the comments above, you're not sure if your formulae are accurate.
The first step is to figure that out.
Select a few well-known points on the globe (North Pole, South Pole, Greenwich UK, etc), and create a test case that invokes convertSphericaltoCartesian() with these coordinates. Check the results and see if they make any sense.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.