简体   繁体   中英

How to quickly calculate what points are within a given distance of my point

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM