Android Google Map how to check if the gps location is inside the circle
Asked Answered
L

4

20

I'm trying to detect if a user is in the radius of a Marker , using the users gps location. I have the marker's coordinates, but I don't know how to calculate whether the user is in the area. I've tried to use the following, but even when the current location is inside the circle I keep getting the "outside" message.

public class MapaEscola extends FragmentActivity {

    private GoogleMap googleMap;
    private Serializable escolas;
    private ProgressDialog dialog;
    private Circle mCircle;
    private Marker mMarker;



    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        getActionBar().setDisplayHomeAsUpEnabled(true);
        getActionBar().setHomeButtonEnabled(true);

        setContentView(R.layout.maps);

        // Loading map
        initilizeMap();

        // Changing map type
        googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);

        // Showing / hiding your current location
        googleMap.setMyLocationEnabled(true);

        // Enable / Disable zooming controls
        googleMap.getUiSettings().setZoomControlsEnabled(true);

        // Enable / Disable my location button
        googleMap.getUiSettings().setMyLocationButtonEnabled(true);

        // Enable / Disable Compass icon
        googleMap.getUiSettings().setCompassEnabled(true);

        // Enable / Disable Rotate gesture
        googleMap.getUiSettings().setRotateGesturesEnabled(true);

        // Enable / Disable zooming functionality
        googleMap.getUiSettings().setZoomGesturesEnabled(true);

        Bundle extra = getIntent().getBundleExtra("extra");
        ArrayList<Escolas> objects = (ArrayList<Escolas>) extra.getSerializable("array");


        try {

            for(int i = 0; i < objects.size(); i ++) {
                System.out.println(" escolas " + objects.get(i).getLatitude() + " " + objects.get(i).getLongitude());

                float latitude = objects.get(i).getLatitude();
                float longitude = objects.get(i).getLongitude();

                googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(-23.316281, -51.155528), 15));

                MarkerOptions options = new MarkerOptions();

                // Setting the position of the marker

                options.position(new LatLng(latitude, longitude));

                googleMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();

                LatLng latLng = new LatLng(latitude, longitude);
                drawMarkerWithCircle(latLng);


                googleMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
                    @Override
                    public void onMyLocationChange(Location location) {
                        float[] distance = new float[2];

                        Location.distanceBetween( mMarker.getPosition().latitude, mMarker.getPosition().longitude,
                                mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance);

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

                    }
                });




            }



        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private void drawMarkerWithCircle(LatLng position){
        double radiusInMeters = 500.0;
        int strokeColor = 0xffff0000; //red outline
        int shadeColor = 0x44ff0000; //opaque red fill

        CircleOptions circleOptions = new CircleOptions().center(position).radius(radiusInMeters).fillColor(shadeColor).strokeColor(strokeColor).strokeWidth(8);
        mCircle = googleMap.addCircle(circleOptions);

        MarkerOptions markerOptions = new MarkerOptions().position(position);
        mMarker = googleMap.addMarker(markerOptions);
    }



    private void initilizeMap() {

        if (googleMap == null) {
            googleMap = ((MapFragment) getFragmentManager().findFragmentById(
                    R.id.map)).getMap();

            // check if map is created successfully or not
            if (googleMap == null) {
                Toast.makeText(getApplicationContext(),
                        "Não foi possível carregar o mapa", Toast.LENGTH_SHORT)
                        .show();
            }
        }
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @Override
    public void onBackPressed() {

        super.onBackPressed();
        finish();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // TODO Auto-generated method stub
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_main, menu);

        return super.onCreateOptionsMenu(menu);
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public boolean onOptionsItemSelected(MenuItem item) {


        switch (item.getItemId()) {

            case android.R.id.home:
                super.onBackPressed();
                finish();

                return true;


        }

        return true;

    }

    @Override
    protected void onResume() {
        super.onResume();
        initilizeMap();
    }


}
Lumbard answered 11/5, 2015 at 14:25 Comment(0)
W
25

I just ran the updated code and figured out what the main problem is.

You should be using the Location passed into the onMyLocationChange() callback, so that it uses your current location to tell if the device is within the circle or not:

googleMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
                @Override
                public void onMyLocationChange(Location location) {
                    float[] distance = new float[2];

                    /*
                    Location.distanceBetween( mMarker.getPosition().latitude, mMarker.getPosition().longitude,
                            mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance);
                            */

                    Location.distanceBetween( location.getLatitude(), location.getLongitude(),
                            mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance);

                    if( distance[0] > mCircle.getRadius() ){
                        Toast.makeText(getBaseContext(), "Outside, distance from center: " + distance[0] + " radius: " + mCircle.getRadius(), Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(getBaseContext(), "Inside, distance from center: " + distance[0] + " radius: " + mCircle.getRadius() , Toast.LENGTH_LONG).show();
                    }

                }
            });

Here is the full working example that I ran, it's a pared down version of your original code:

public class MainActivity extends ActionBarActivity {

    private GoogleMap googleMap;
    private Serializable escolas;
    private ProgressDialog dialog;
    private Circle mCircle;
    private Marker mMarker;



    @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);

        setContentView(R.layout.activity_main);

        // Loading map
        initilizeMap();

        // Changing map type
        googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);

        // Showing / hiding your current location
        googleMap.setMyLocationEnabled(true);

        // Enable / Disable zooming controls
        googleMap.getUiSettings().setZoomControlsEnabled(true);

        // Enable / Disable my location button
        googleMap.getUiSettings().setMyLocationButtonEnabled(true);

        // Enable / Disable Compass icon
        googleMap.getUiSettings().setCompassEnabled(true);

        // Enable / Disable Rotate gesture
        googleMap.getUiSettings().setRotateGesturesEnabled(true);

        // Enable / Disable zooming functionality
        googleMap.getUiSettings().setZoomGesturesEnabled(true);

       // Bundle extra = getIntent().getBundleExtra("extra");
        //ArrayList<Escolas> objects = (ArrayList<Escolas>) extra.getSerializable("array");


        try {
               //test outside
               double mLatitude = 37.77657;
               double mLongitude = -122.417506;


                //test inside
                //double mLatitude = 37.7795516;
                //double mLongitude = -122.39292;


                googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(mLatitude, mLongitude), 15));

                MarkerOptions options = new MarkerOptions();

                // Setting the position of the marker

                options.position(new LatLng(mLatitude, mLongitude));

                //googleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();

                LatLng latLng = new LatLng(mLatitude, mLongitude);
                drawMarkerWithCircle(latLng);


                googleMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {
                    @Override
                    public void onMyLocationChange(Location location) {
                        float[] distance = new float[2];

                        /*
                        Location.distanceBetween( mMarker.getPosition().latitude, mMarker.getPosition().longitude,
                                mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance);
                                */

                        Location.distanceBetween( location.getLatitude(), location.getLongitude(),
                                mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance);

                        if( distance[0] > mCircle.getRadius()  ){
                            Toast.makeText(getBaseContext(), "Outside, distance from center: " + distance[0] + " radius: " + mCircle.getRadius(), Toast.LENGTH_LONG).show();
                        } else {
                            Toast.makeText(getBaseContext(), "Inside, distance from center: " + distance[0] + " radius: " + mCircle.getRadius() , Toast.LENGTH_LONG).show();
                        }

                    }
                });




        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private void drawMarkerWithCircle(LatLng position){
        double radiusInMeters = 500.0;
        int strokeColor = 0xffff0000; //red outline
        int shadeColor = 0x44ff0000; //opaque red fill

        CircleOptions circleOptions = new CircleOptions().center(position).radius(radiusInMeters).fillColor(shadeColor).strokeColor(strokeColor).strokeWidth(8);
        mCircle = googleMap.addCircle(circleOptions);

        MarkerOptions markerOptions = new MarkerOptions().position(position);
        mMarker = googleMap.addMarker(markerOptions);
    }



    private void initilizeMap() {

        if (googleMap == null) {
            googleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(
                    R.id.map)).getMap();

            // check if map is created successfully or not
            if (googleMap == null) {
                Toast.makeText(getApplicationContext(),
                        "Não foi possível carregar o mapa", Toast.LENGTH_SHORT)
                        .show();
            }
        }
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    @Override
    public void onBackPressed() {

        super.onBackPressed();
        finish();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // TODO Auto-generated method stub
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.menu_main, menu);

        return super.onCreateOptionsMenu(menu);
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    public boolean onOptionsItemSelected(MenuItem item) {


        switch (item.getItemId()) {

            case android.R.id.home:
                super.onBackPressed();
                finish();

                return true;


        }

        return true;

    }

    @Override
    protected void onResume() {
        super.onResume();
        initilizeMap();
    }


}

Results of Inside the circle:

Inside

Results of outside the circle:

Outside

Woodbury answered 11/5, 2015 at 15:16 Comment(3)
Hi, Daniel, thank you for your help, but I'm still getting the same resultsLumbard
@WARpoluido Take a look at the updated answer. You also had an un-necessary call to getMap() in there, take a look at the full code.Woodbury
@DanielNugent Hi sir i am new to this google maps. i have multiple circles. Is there any way to find my current location is pointed in which circle?Excellence
G
2

@Daniel Nugent: imho getRadius() will return the radius and not the diameter so the "/2" is wrong

@WARpoluido: I cant see that the mMarker variable is updated when the location changes. Why dont you use the value given to onMyLocationChange()?

Location.distanceBetween( mCircle.getCenter().latitude, mCircle.getCenter().longitude, location.getLatitude(), location.getLongitude(), distance);
if( distance[0] > mCircle.getRadius() ){
...
Geoffrey answered 11/5, 2015 at 17:53 Comment(2)
Ahh, you're right. I was confusing diameter and radius. Good catch! Also, you're right about the location! Good eye, I had to run it to see that.Woodbury
I just upvoted your answer, because you deserve some credit for this. Thanks for correcting the radius/diameter error from my initial answer!Woodbury
K
2

Hi I have got mine working correctly with this code

//Getting current location
private void getCurrentLocation() {
    mMap.clear();
    //Creating a location object
    Location location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
    if (location != null) {
        //Getting longitude and latitude
        longitude = location.getLongitude();
        latitude = location.getLatitude();
        //moving the map to location
        moveMap();
    }

    Circle circle = mMap.addCircle(new CircleOptions()
                    .center(new LatLng(54.773097, -6.557841))
                    .radius(55)
                    .strokeColor(Color.RED)
    );



    pLong  = location.getLongitude();
    pLat = location.getLatitude();

    float[] distance = new float[2];


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

    if( distance[0] > circle.getRadius()  ){
        Toast.makeText(getBaseContext(), "You are not in a bunker", Toast.LENGTH_LONG).show();
    } else {
        Toast.makeText(getBaseContext(), "You are inside a bunker", Toast.LENGTH_LONG).show();
    }

}

Inside the circle

Outside the circle

Kesley answered 5/4, 2016 at 17:32 Comment(0)
D
0

The accepted solution of Daniel Nugent isn't so good anymore because setOnMyLocationChangeListener is deprecated now.

Here is current way how to do it in fragment - change getActivity() with this for Activity:

private boolean mLocationPermissionGranted;

// The geographical location where the device is currently located. That is, the last-known
// location retrieved by the Fused Location Provider.
private Location mLastKnownLocation;
private long UPDATE_INTERVAL = 10 * 1000;  /* 10 secs */
private long FASTEST_INTERVAL = 2000; /* 2 sec */
private FusedLocationProviderClient mFusedLocationProviderClient;

private void addLocationChangeListener(){
        // Construct a FusedLocationProviderClient.
        mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getActivity());

        // Create the location request to start receiving updates
        LocationRequest mLocationRequest = new LocationRequest();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setInterval(UPDATE_INTERVAL);
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
        //mLocationRequest.setMaxWaitTime(0);
        //mLocationRequest.setSmallestDisplacement(0);

        // Create LocationSettingsRequest object using location request
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
        builder.addLocationRequest(mLocationRequest);
        LocationSettingsRequest locationSettingsRequest = builder.build();

        // Check whether location settings are satisfied
        // https://developers.google.com/android/reference/com/google/android/gms/location/SettingsClient
        SettingsClient settingsClient = LocationServices.getSettingsClient(getActivity());
        settingsClient.checkLocationSettings(locationSettingsRequest);


        // new Google API SDK v11 uses getFusedLocationProviderClient(this)
        if (mLocationPermissionGranted) {
            mFusedLocationProviderClient.requestLocationUpdates(mLocationRequest,
                    new LocationCallback() {
                        @Override
                        public void onLocationResult(LocationResult locationResult) {
                            // do work here
                            Location location = locationResult.getLastLocation();
                        }
                    },
                    Looper.myLooper());
        } else {
            getLocationPermission();
        }
    }
Distemper answered 22/12, 2017 at 20:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.