androidgoogle-mapsandroid-geofence

Cannot add multiple circles and map markers


I am creating a geofence application and it has a map interface for the user to view where the geofences are located. The problem I have is whenever i load in the coordinates, it only draws one circle and one marker, but the geofence can be entered and exited as intended. At this time, I don't have a physical device to test on, so I'm relying on the emulator.

Here is a GIF of it in action

private void loadGeofencesFromDatabase() {

    for (Map.Entry<String, LatLng> entry : Constants.BAY_AREA_LANDMARKS.entrySet()) {

        mGeofenceList.add(new Geofence.Builder()
                // Set the request ID of the geofence. This is a string to identify this
                // geofence.
                .setRequestId(entry.getKey())

                // Set the circular region of this geofence.
                .setCircularRegion(
                        entry.getValue().latitude,
                        entry.getValue().longitude,
                        Constants.GEOFENCE_RADIUS_IN_METERS
                )

                // Set the expiration duration of the geofence. This geofence gets automatically
                // removed after this period of time.
                .setExpirationDuration(Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS)

                // Set the transition types of interest. Alerts are only generated for these
                // transition. We track entry and exit transitions in this sample.
                .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
                        Geofence.GEOFENCE_TRANSITION_EXIT)

                // Create the geofence.
                .build());

        GeofenceLatLngCoordinates = new ArrayList<>();
        GeofenceLatLngCoordinates.add(new LatLng(entry.getValue().latitude, entry.getValue().longitude));

        GEOFENCE_RADIUS = Constants.GEOFENCE_RADIUS_IN_METERS;

        addGeofences();

    }
}

Here is the method responsible for drawing the circle and markers on the map. It retrieves the coordinates from the ArrayList and then attempts to draw the circle and markers on the map using for loop.

private void drawGeofence() {
    Log.d(TAG, "GEOFENCE: Drawing Geofence on Map");

    for (LatLng latLng : GeofenceLatLngCoordinates){

        CircleOptions circleOptions = new CircleOptions()
                .center(new LatLng(latLng.latitude, latLng.longitude))
                .strokeColor(Color.argb(50, 70,70,70))
                .fillColor( Color.argb(100, 150,150,150) )
                .strokeColor(Color.RED)
                .strokeWidth(5)
                .radius(GEOFENCE_RADIUS);
        geoFenceLimits = map.addCircle( circleOptions );

        MarkerOptions markerOptions = new MarkerOptions()
                .position(new LatLng(latLng.latitude, latLng.longitude))
                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE))
                .title("My Geofence Location");

        testMark = map.addMarker(markerOptions);
    }

}

Solution

  • You are creating your GeofenceLatLngCoordinates = new ArrayList<>(); on each iteration of the for loop.

    Just move that line before the for loop:

    private void loadGeofencesFromDatabase() {
        GeofenceLatLngCoordinates = new ArrayList<>();
        GEOFENCE_RADIUS = Constants.GEOFENCE_RADIUS_IN_METERS;
    
        for (Map.Entry<String, LatLng> entry : Constants.BAY_AREA_LANDMARKS.entrySet()) {
            mGeofenceList.add(new Geofence.Builder()
                    // Set the request ID of the geofence. This is a string to identify this
                    // geofence.
                    .setRequestId(entry.getKey())
    
                    // Set the circular region of this geofence.
                    .setCircularRegion(
                            entry.getValue().latitude,
                            entry.getValue().longitude,
                            Constants.GEOFENCE_RADIUS_IN_METERS
                    )
    
                    // Set the expiration duration of the geofence. This geofence gets automatically
                    // removed after this period of time.
                    .setExpirationDuration(Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS)
    
                    // Set the transition types of interest. Alerts are only generated for these
                    // transition. We track entry and exit transitions in this sample.
                    .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
                            Geofence.GEOFENCE_TRANSITION_EXIT)
    
                    // Create the geofence.
                    .build());
    
            GeofenceLatLngCoordinates.add(new LatLng(entry.getValue().latitude, entry.getValue().longitude));
            addGeofences();
        }
    }