Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate random LatLng given device location and radius

I am trying to generate random points on the map near a given location. I have a circle shape which surrounds the user location with a radius of 100, and I would like to generate random LatLng coordinates within this circle area. I have come up with the following function so far, but the point markers are still appearing outside the circle range.

    double lat = location.getLatitude();
    double lon = location.getLongitude();

    for (int i = 0; i < markers.size(); i++) {
        Marker mrk = markers.get(i);

            Random random = new Random();


            double radiusInDegrees =mCircle.getRadius();

            double u = random.nextDouble();
            double v = random.nextDouble();
            double w = radiusInDegrees * Math.sqrt(u);
            double t = 2 * Math.PI * v;
            double x = w * Math.cos(t);
            double y = w * Math.sin(t);

            // Adjust the x-coordinate for the shrinking of the east-west distances
            double new_x = x / Math.cos(lat);

            double newLongitude = new_x + lon;
            double newLatitude = y + lat;


            mrk.setPosition(new LatLng(newLatitude,newLongitude));

    }
like image 213
kabuto178 Avatar asked Nov 28 '15 21:11

kabuto178


2 Answers

with the help of this https://gis.stackexchange.com/a/68275

I am able to make a function which generate random LatLng point within certain radius, where radius is in meter.

public LatLng getRandomLocation(LatLng point, int radius) {

        List<LatLng> randomPoints = new ArrayList<>();
        List<Float> randomDistances = new ArrayList<>();
        Location myLocation = new Location("");
        myLocation.setLatitude(point.latitude);
        myLocation.setLongitude(point.longitude);

        //This is to generate 10 random points
        for(int i = 0; i<10; i++) {
            double x0 = point.latitude;
            double y0 = point.longitude;

            Random random = new Random();

            // Convert radius from meters to degrees
            double radiusInDegrees = radius / 111000f;

            double u = random.nextDouble();
            double v = random.nextDouble();
            double w = radiusInDegrees * Math.sqrt(u);
            double t = 2 * Math.PI * v;
            double x = w * Math.cos(t);
            double y = w * Math.sin(t);

            // Adjust the x-coordinate for the shrinking of the east-west distances
            double new_x = x / Math.cos(y0);

            double foundLatitude = new_x + x0;
            double foundLongitude = y + y0;
            LatLng randomLatLng = new LatLng(foundLatitude, foundLongitude);
            randomPoints.add(randomLatLng);
            Location l1 = new Location("");
            l1.setLatitude(randomLatLng.latitude);
            l1.setLongitude(randomLatLng.longitude);
            randomDistances.add(l1.distanceTo(myLocation));
        }
        //Get nearest point to the centre
        int indexOfNearestPointToCentre = randomDistances.indexOf(Collections.min(randomDistances));
        return randomPoints.get(indexOfNearestPointToCentre);
    }

The purpose of for loop is just to ensure to get nearest random point, as I have seen points were getting out of circle as I am increasing the radius. You may remove loop.

like image 110
Abhishek Avatar answered Oct 24 '22 00:10

Abhishek


This answer should help. It looks like what you have execpt for converting the radiusfrom meters to degrees.

  // Convert radius from meters to degrees
double radiusInDegrees = radius / 111000f;

See link here.

like image 1
Eric Engel Avatar answered Oct 24 '22 01:10

Eric Engel