2

I am new to programming android and having a problem with an map application I am working on. The app allows for circles to be place on the map through a click and if the current location is inside the circle a message is displayed, also if outside the circle a different message is displayed. The problem is during the onStart check of the circles it only detects inside or outside of the last created circle instead of all available ones. I am not sure what is causing this problem. Code Snippet follows:

     // Opening the sharedPreferences object
    sharedPreferences = getSharedPreferences("location", 0);

    // Getting number of locations already stored
    locationCount = sharedPreferences.getInt("locationCount", 0);

    // Getting stored zoom level if exists else return 0
    //String zoom = sharedPreferences.getString("zoom", "0");

    // If locations are already saved
    if(locationCount!=0){

        String lat = "";
        String lng = "";

        // Iterating through all the locations stored
        for(int i=0;i<locationCount;i++){

            // Getting the latitude of the i-th location
            lat = sharedPreferences.getString("lat"+i,"0");

            // Getting the longitude of the i-th location
            lng = sharedPreferences.getString("lng"+i,"0");

            double latitude = Double.parseDouble(lat);
            double longitude = Double.parseDouble(lng);

            startCircle = googleMap.addCircle(new CircleOptions().center(new LatLng (latitude, longitude)).radius(CIRCLE_RADIUS).fillColor(0x55888888));
        }

    }
public void onStart(){
    super.onStart();

    //Create a criteria object to retrieve provider
    Criteria criteria = new Criteria();
    // Set accuracy of criteria to address level
     criteria.setAccuracy(Criteria.ACCURACY_FINE);
    //Get the name of the best provider
    String provider = locationManager.getBestProvider(criteria, true);
    //Get Current Location
    Location myLocation = locationManager.getLastKnownLocation(provider);
    double lat = myLocation.getLatitude();
    double lon = myLocation.getLongitude();
    LatLng latlng = new LatLng(lat,lon);
    if(startCircle == null){
        return;
    }
    else{
        float[] distance = new float[2];
        marker = googleMap.addMarker(new MarkerOptions().position(latlng).visible(false));
      myLocation.distanceBetween( marker.getPosition().latitude, marker.getPosition().longitude,
                startCircle.getCenter().latitude, startCircle.getCenter().longitude, distance);

        if( distance[0] < startCircle.getRadius()){

            Toast.makeText(getBaseContext(), "Inside", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(getBaseContext(), "Outside", Toast.LENGTH_LONG).show();

        }

    }
}

4 Answers4

0

in Javascript I used:

google.maps.geometry.poly.containsLocation(pos, selectedPolygon);

This method available in google-maps API 3, (Sounds like you can't)

But try to write some math function based on circle area.

it really easy. Calculate distance between 2 coordinates:

public static float distFrom2LocationsInMeter() {
  
            
    double lat1 = ...;
    double lng1 = ...;
    double lat2 = ...;
    double lng2 =...;
    
    
    //lat1 /= 1000000; // sometimes Android returns location in 10^6 form
    //lng1 /= 1000000;      
    
    //lat2 /= 1000000;          
    // lng2 /= 1000000; 
    
                    
    
    double earthRadius = 3958.75;
    double dLat = Math.toRadians(lat2-lat1);
    double dLng = Math.toRadians(lng2-lng1);
    double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
               Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
               Math.sin(dLng/2) * Math.sin(dLng/2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    double dist = earthRadius * c;

        
    int meterConversion = 1609;

    return Float.valueOf((float)(dist * meterConversion ));
    }

After just check your radius:

if R > distFrom2LocationsInMeter() // you inside

if R < distFrom2LocationsInMeter() // you outside

Community
  • 1
  • 1
Maxim Shoustin
  • 77,483
  • 27
  • 203
  • 225
0

The problem is during the onStart check of the circles it only detects inside or outside of the last created circle instead of all available ones. I am not sure what is causing this problem.

the problem is when you create a circle you are overwriting the last circle created so the startCircle is always the last one created. You will need to keep a list of all the circles you plot on the map;

to look how to check if a point is inside an object I would check out this link as it prooved very useful to me when I needed to do this

How can I determine whether a 2D Point is within a Polygon?

Community
  • 1
  • 1
tyczj
  • 71,600
  • 54
  • 194
  • 296
0

Toast.makeText(MapActivity.this,String.valueOf(isInside(latitude_location_place, longitude_location_place,0.002,map.getMyLocation().getLatitude(),map.getMyLocation().getLongitude())) , Toast.LENGTH_SHORT).show();

public boolean isInside(double circle_x, double circle_y, double rad, double x, double y) {

    map.addCircle(new CircleOptions()
            .center(new LatLng(circle_x, circle_y))
            .radius(200)
            //its about 20 meter
            // you most set rad=0.002 for 20 meter
            .strokeColor(Color.RED)
            .fillColor(R.color.color_circle));

    map.addMarker(new MarkerOptions().position(new LatLng(x, y)));

    if ((x - circle_x) * (x - circle_x) +
            (y - circle_y) * (y - circle_y) <= rad*rad)
        return true;
    else
        return false;
}
  • While this code may provide a solution to the question, it's better to add context as to why/how it works. This can help future users learn, and apply that knowledge to their own code. You are also likely to have positive feedback from users in the form of upvotes, when the code is explained. – borchvm May 18 '20 at 12:38
0

Example:

Toast.makeText(MapActivity.this,String.valueOf(isInside(latitude_location_place, longitude_location_place,0.002,map.getMyLocation().getLatitude(),map.getMyLocation().getLongitude())) , Toast.LENGTH_SHORT).show();


public boolean isInside(double circle_x, double circle_y,
                            double rad, double x, double y) {


        map.addCircle(new CircleOptions()
                .center(new LatLng(circle_x, circle_y))
                .radius(200)
                //its about 20 meter
                // you most set rad=0.002 for 20 meter
                .strokeColor(Color.RED)
                .fillColor(R.color.color_circle));

        map.addMarker(new MarkerOptions().position(new LatLng(x, y)));

        if ((x - circle_x) * (x - circle_x) +
                (y - circle_y) * (y - circle_y) <= rad*rad)
            return true;
        else
            return false;
    }
borchvm
  • 3,533
  • 16
  • 44
  • 45