Source: https://developers.woosmap.com/products/geofencing-sdk/android-sdk/guides/monitor-pois/

> For clean Markdown of any page, append `.md` to the page URL.

> For a complete documentation index, see https://developers.woosmap.com/llms.txt

# Monitor places with custom geofence



##  Create and monitor custom Geofences

Use region monitoring to determine when the user enters or leaves a geographic region.

Region monitoring (also known as geofencing) combines awareness of the user's current location with awareness of the
user's proximity to locations that may be of interest. This region is a way for your app to be alerted when the user
enters or exits a geographical region. To mark a location of interest, you specify its latitude and longitude. To adjust
the proximity for the location, you add a radius. The latitude, longitude, and radius define a Geofence, creating a
circular area, or isochrone geofence, around the location of interest. Find more details about Geofences in
the [Geofencing documentation](/products/geofencing-sdk/geofencing/)

### Set up for Geofence monitoring

The first step in requesting Geofence monitoring is to set `RegionReadyListener`, this should be done as early as
possible in your `mainActivity` on the method `onCreate`.

```java
@Override
protected void onCreate(Bundle savedInstanceState) {

    // [...] //

    this.woosmap.setRegionReadyListener( new WoosRegionReadyListener() );

}
``` 

### Woosmap Region Ready Listener

In your `mainActivity`, create a listener connected to the interface `Woosmap.RegionReadyListener` and set a callback to
retrieve Regions event. This callback is triggered when a region is created.

```java
public class WoosRegionReadyListener implements Woosmap.RegionReadyListener {  
    public void RegionReadyCallback(Region region) { 
            // region data
  }  
}  
```

On the object `Region`, there are a boolean `didEnter` that indicate if you are inside or outside of the region based on
the system detection. The system only manages circle geofence so ignore for type isochrone.
Another boolean `isCurrentPositionInside` share the same information but based on the position
detection (calculated by the SDK and not by the device's Location Mannager). So you can get `didEnter` at `false`
and `isCurrentPositionInside`at `true`if the position is inside the region and the system don't detect the transition.

By experience, the region enter/exit event from android is triggered on new position inside the region or outside.
Indeed the events are not triggered on the crossing limit of the region. So it's important to have a minimum radius of
the region should be set between 100 - 150 meters for circle regions and 3 - 5 minutes for isochrone regions.

Regions have an associated identifier, which this method uses to look up information related to the region and perform
the associated action.

You can recover the regions created in the database of SDK as follows :

```java
Region[] regionList = WoosmapDb.getInstance(mContext, true).getRegionsDAO().getAllRegions();
```

You can recover all the logs of region event in the database of SDK as follows :

```java
RegionLog[] regionLogList = WoosmapDb.getInstance(mContext, true).getRegionLogsDAO().getAllRegionLogs();
``` 

### Woosmap RegionLog Ready Listener

In your `mainActivity`, create a listener connected to the interface `Woosmap.RegionLogReadyCallback` and set a callback
to retrieve Regions Log event. Whenever the user crosses the boundary of one of your app's registered regions, the
system notifies your app and trigger the `RegionLogReadyCallback`.

```java
public class WoosRegionLogReadyListener implements Woosmap.RegionLogReadyListener {
    public void RegionLogReadyCallback(RegionLog regionLog) {
            // region log event data
    }
}
```

### Create a custom region

A region is an area centered on a geographic coordinate. There are two types of region, `circle` and `isochrone`. You can define one using a `LatLng` object. The radius of the region object defines its boundary: The radius in meters for type circle, a number higher than 100 is recommended. The travel duration in seconds for type isochrone, a number higher than 180 seconds is recommended. You define the regions you want to monitor and register them with the system
by calling the `addGeofence(center: LatLng, radius: float, type: string)` method of `Woosmap.getInstance()`. The system
monitors your regions until you explicitly ask it to stop.

```java
Woosmap.getInstance().addGeofence( id, latLng, 100, "circle");
```

The limit of numbers of circular regions monitored can not been exceed. Indeed, regions are shared resources that rely on
specific hardware capabilities. To ensure that all apps can participate in region monitoring, android prevents any
single app from monitoring more than 100 regions simultaneously.

To work around this limitation, monitor only regions that are close to the user’s current location. As the user moves,
update the list based on the user’s new location.

Be Careful, to have a monitoring regions the user must allow permissions to share the position all time.

#### Create a custom isochrone region

To monitor an isochrone geofence, the Geofencing SDK regularly request [Woosmap Distance API](/products/distance-api/features/isochrone/). You can choose between using or not traffic data by enabling/disabling `distanceWithTraffic` parameter:

```java
WoosmapSettings.setDistanceWithTraffic(true);
```

Remember to define a Woosmap key before create isochrone geofences.

```java
WoosmapSettings.privateKeyWoosmapAPI = woosmapPrivateKey;
    
Woosmap.getInstance().addGeofence( id, latLng, 180, "isochrone"); // 180 seconds -> 3 minutes
```

At any time, you can also modify the travel mode related to the user. Three travel mode are available: `driving`, `walking` and `cycling`. 
Use the following method to modify the travel mode:

```java
WoosmapSettings.setModeDistance("driving");
```

### Remove regions

To remove all regions created, you can use this method:

```java
Woosmap.getInstance().removeGeofences()
```

To remove a specific region, you can use this method with the id of the region:

```java
Woosmap.getInstance().removeGeofences(String id)
```

You can also replace a monitored geofence by a new one:

```java
Woosmap.getInstance().replaceGeofence(
        String: removedGeofenceId,
        String: createdGeofenceId,
        LatLng: coordinates, 
        float: radius,
        String: type
        );
```

If you don't use the same id for `removedGeofenceId` and `createdGeofenceId`, ensure that the `createdGeofenceId` is not already used by a monitored geofence.
