11

I have a circle on my map. Now I want to detect if the user (or me) is inside the circle.

 Circle circle = map.addCircle(new CircleOptions()
     .center(new LatLng(14.635594, 121.032962))
     .radius(55)
     .strokeColor(Color.RED)
     );

I have this code:

 LocationManager lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
    LocationListener ll = new myLocationListener();
    lm.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0,ll);



     Location.distanceBetween( pLat,pLong,
                circle.getCenter().latitude, circle.getCenter().longitude, distance);

            if( distance[0] > circle.getRadius()  ){
                Toast.makeText(getBaseContext(), "Outside", Toast.LENGTH_LONG).show();
            } else {
                Toast.makeText(getBaseContext(), "Inside", Toast.LENGTH_LONG).show();
            }

And on myLocationListener I have this:

public void onLocationChanged(Location location) {
            // TODO Auto-generated method stub
             pLong  = location.getLongitude();
             pLat = location.getLatitude();

        }

It works correctly if I parameter inside distanceBetween is the coordinates of marker, however, the toast displays Outside even though my location is inside the radius.

enter image description here

Any ideas how to do this correctly? Please help. Thanks!

EDIT

I discovered something odd.

On the picture, you can see I have a textView above which has 5 numbers (circle Latitude, circle longitude, distance at index 0 , distance at index 1 , distance2). distance is a float array to store the distance between the center of the circle and the user location. I set the radius to 100, and I think the unit is meters, however, as you can see, the values at the distance array are : 1.334880E7 , -81.25308990478516 , -10696092987060547 . What is the formula for the computation of the distance? And also, 1.something times 10 raise to 7 is about 13 million which is really greater than 100. Please help its really confusing right now. According to documentation of Circle (The radius of the circle, specified in meters. It should be zero or greater.) and distanceBetween (Computes the approximate distance in meters between two locations) so I don't know why is this the result.

enter image description here

Jeongbebs
  • 4,100
  • 7
  • 34
  • 60
  • 2
    calculate the distance to the center of the circle and the distance from the circles border to the center (radius in kn/miles) and check wether it is ind the radius? – A.S. Nov 18 '13 at 09:24
  • chances are your location on the map is not the location that is getting returned from your location client – tyczj Nov 18 '13 at 15:24

3 Answers3

4

tl;dr? jsFiddle here - look at your console output.

Basically there're two ways to do this:

  1. Check if the (marker of) the user is inside the Circle Bounds
  2. Compute the distance between the user and the center of the Circle. Then check if it is equal or smaller than the Circle Radius. This solution needs the spherical library to work.

Circle Bounds

Just add a circle:

circle = new google.maps.Circle( {
        map           : map,
        center        : new google.maps.LatLng( 100, 20 ),
        radius        : 2000,
        strokeColor   : '#FF0099',
        strokeOpacity : 1,
        strokeWeight  : 2,
        fillColor     : '#009ee0',
        fillOpacity   : 0.2
    } )

and then check if the marker is inside:

circle.getBounds().contains( new google.maps.LatLng( 101, 21 ) );

At a first glance you might think this works. But it doesn't. In the background google (still) uses a rectangle, so everything inside the rectangular bounding box, but outside the circle will be recognized as inside the latLng bounds. It's wrong and a known problem, but it seems Google doesn't care.

If you now think that it would work with rectangular bounds, then you're wrong. Those don't work either.

Spherical Distance

The easiest and best way is to measure the distance. Include the spherical library by appending &library=spherical to your google maps script call. Then go with

google.maps.geometry.spherical.computeDistanceBetween( 
    new google.maps.LatLng( 100, 20 ),
    new google.maps.LatLng( 101, 21 )
) <= 2000;
kaiser
  • 21,817
  • 17
  • 90
  • 110
3

I know this question had been asked more than a year ago but I have the same problem and fixed it using the distanceBetween static function of Location.

float[] distance = new float[2];

Location.distanceBetween(latLng.latitude, latLng.longitude, circle.getCenter().latitude,circle.getCenter().longitude,distance);

if ( distance[0] <= circle.getRadius())
{
    // Inside The Circle
}
else
{
    // Outside The Circle
}
Christian Abella
  • 5,747
  • 2
  • 30
  • 42
0

Use GoogleMap.setOnMyLocationChange(OnMyLocationChangeListener) instead of LocationManager. This way you will get Locations that are the same as blue dot locations.

MaciejGórski
  • 22,187
  • 7
  • 70
  • 94